第28回 Rails勉強会@東北に参加

https://www.facebook.com/events/378705102216002/

OzakiさんによるRails4.0ネタでした。
はじめにこちらのスライド。
https://speakerdeck.com/alindeman/rails-4-dot-0-whirlwind-tour

その中から特にStrong ParametersとTurbolinksについては、スライド見終わった後、RailsCastsをネタに皆で手を動かしながらワイワイとやりました。
http://railscasts.com/episodes/371-strong-parameters
http://railscasts.com/episodes/390-turbolinks

Turbolinksはこのままリリースされたらギャッという人がたくさん出そうでだいぶアレ。



後、スライド中で出てきたnoneというメソッドやallがActiveRecord::Relationを返す件について↓

#Relation#none 
# Chainable null object 
> Post.none 
#<ActiveRecord::Relation []> 
# Doesn't hit database > 
Post.none.to_sql 
"" 
> Post.none.to_a 
[]


#Relation#all returns a relation (chainable) 
# Rails 3 
> Post.all.class 
Array
# Rails 4 
> Post.all.class 
ActiveRecord::Relation 
> Post.all.to_a.class
 Array

勉強会中に、jQuery関数型言語っぽくチェーンして書けて、条件分岐を書くケースが減るという事かなとか言いましたが、実際の使用ケースを見ないとわからないという意見がありました。
で、記事に書いてみようかと思ったら、Active Record Query Interface — Ruby on Rails Guidesここに書いてあったのでまるまる引用。

9 Null Relation
The none method returns a chainable relation with no records. Any subsequent conditions chained to the returned relation will continue generating empty relations. This is useful in scenarios where you need a chainable response to a method or a scope that could return zero results.

Post.none # returns an empty Relation and fires no queries.


# The visible_posts method below is expected to return a Relation.
@posts = current_user.visible_posts.where(name: params[:name])
 
def visible_posts
  case role
  when 'Country Manager'
    Post.where(country: country)
  when 'Reviewer'
    Post.published
  when 'Bad User'
    Post.none # => returning [] or nil breaks the caller code in this case
  end
end

Rails4.0では、noneでActiveRecord::Relationを返してくれるので、上記のようにcurrent_user.visible_postsのところで空配列が来てるかの条件分岐を入れずに、jQueryのようにチェーンして書けると。
ScalaのOptionのNoneとかも彷彿とさせますね。

Rails3.2までの場合だと、例えば[]やnilを返してそれをチェックするとか、visible_posts_user_nameといったvisible_postsとwhere(name: params[:name])を一気に処理するメソッドを作成するといったアプローチになるかと。

Rails4.0の場合は、visible_postsメソッドを他でも利用出来て、再利用性を高めて、さらに重複を排除してコードを書けるようになるというのがメリットかなあと。

allがActiveRecord::Relationを返すようになるというのも同様な流れな気が。で、allがActiveRecord::Relation返せば、scopedはいらない子になるのでDEPRECATIONと。
もっともallの場合は、all呼ばないでwhere呼ぶ事が多い気がするので使用ケースは少ないかと。
個人的にはこんな風に理解しました。


参加の皆様お疲れ様でした。