こんにちは。
Railsで、親子関係のrelationで子がない親だけを取り出すscopeの書き方についてです。
親子関係のrelation
例えば、次のような親子関係のモデルがあるとします。
class Parent < ApplicationRecord
  has_many :children
end
class Child < ApplicationRecord
  belongs_to :parent
end
この場合、Parentモデルにはhas_many :childrenという関連があり、Childモデルにはbelongs_to :parentという関連があります。
このとき、Parentモデルには、子がいる親と子がいない親が存在します。
子がない親だけを取り出すscope
子がない親だけを取り出すためのscopeを書くには、次のようにします。
class Parent < ApplicationRecord
  has_many :children
  scope :without_children, -> {
    left_joins(:children).where(children: { id: nil })
  }
end
このscopeは、Parentモデルに対してwithout_childrenというメソッドを追加します。
このメソッドは、left_joins(:children)でchildrenテーブルを左外部結合し、where(children: { id: nil })でchildrenテーブルのidがnilであるレコードを取り出します。
このようにすることで、子がない親だけを取り出すことができます。
今回はこのあたりで。
![[Rails] 特定の条件でデータを取得する時のサブクエリの書き方](/assets/ogp/rails-subquery-for-specific-conditions.webp)
![[Rails]insert_allの返り値に注意しないといけないよって話](/assets/ogp/rails-insert-all-return-value.webp)