別の has_many 関連付けから項目をフィルターするだけの has_many 関連付けを作成する方法はありますか?

概要

基本的には has_many 関連付けがあります。元の関連付けから項目をフィルターするだけの別の関連付けを作成したいと考えています。

class Track
  belongs_to :playlist
end

class Playlist
  has_many :tracks

  has_many :five_start_tracks, -> { what to write here? }
  has_many :long_tracks, -> { ... }
end

それを行う方法はありますか、それともそのまま使用する必要がありますか

def five_star_tracks
  tracks.where(rating: 5)
end
def long_tracks
  tracks.where("duration_seconds > ?", 600)
end

解決策

はい、has_many 関連付けにスコープを追加できます。ただし、Ruby on Rails では名前からクラス名を推測できなくなっているため、関連付けにクラス名も追加する必要があります。

class Playlist
  has_many :tracks

  has_many :five_start_tracks, -> { where(rating: 5) }, class_name: 'Track'
  has_many :long_tracks, -> { where('duration_seconds > ?', 600) }, class_name: 'Track'
end

または、特殊な関連付けの長いリストを定義するときに読みやすさを向上させる with_options を使用します。

class Playlist
  has_many :tracks

  with_options class_name: 'Track' do
    has_many :five_start_tracks, -> { where(rating: 5) }
    has_many :long_tracks, -> { where('duration_seconds > ?', 600) }
  end
end