has_manyで関連元のオブジェクトに依存した条件を付けたいとき

Railsのモデルで、has_manyの関連で関連先を絞り込むために条件を付けたいときがありますよね。

Rails Guidesにもあるように、 第2引数でlambda式を渡して条件を付けることができます。

has_many :users, -> { where("created_at > ?", Time.now) }

こんな感じで。

where以外にorderなども使えるので、予めソートしておきたい場合などに便利です。

これぐらいであれば、Rails Guidesや書籍、他のサイトにも載っている情報だと思います。

 

しかし、こんなシーンではどうしますか?

「関連元のオブジェクトのフィールドに依存した条件を付けたい」

つまり、has_manyを書いているモデル自身のフィールド値を、このlambda式内に伝える方法です。

実は、このやり方はRails Guidesでも紹介されていない上に、あまりググっても出てこない情報です。(私調べ)

こんな風に、lambdaの引数として受け取ることができます。

class User < ActiveRecord::Base
  has_many :birthday_events,
    ->(user) { where starts_on: user.birthday },
    class_name: 'Event'
end

抜粋元:
rails/activerecord/lib/active_record/associations.rb at master · rails/rails

 

この様に、Rails Guidesなどのドキュメントになっていないために、機能として知られないものは他にもあります。

Railsでの開発に慣れてきた方は、ぜひRailsのソースコードを読んでみてください!僕もまだまだ読み始めですが、色んな新しい機能の発見や、Railsの構造、そしてRubyのテクニックを学ぶことができます。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください