2016-08-27 12 views
2

私は次のモデルがあります:ActiveRecordの親モデルから子モデルの関連付けの条件を適用する方法は?

class Staff < ApplicationRecord 
    has_many :seminars 
end 

class Seminar < ApplicationRecord 
    belongs_to :staff 
    has_many :schedules 
    has_many :future_schedules, -> { future }, class_name: 'Schedule' 
    has_many :past_schedules, -> { past }, class_name: 'Schedule' 
end 

class Schedule < ApplicationRecord 
    belongs_to :seminar 

    scope :future, -> { where('starts_at > ?', Time.now) } 
    scope :past, -> { where('ends_at > ?', Time.now) } 
end 

は、私は簡単に行うことができます:

  1. スタッフ
  2. セミナー
  3. スケジュール

の関係は単純であるseminar.future_schedules & seminar.past_schedulesが、ここはissですue:将来的にスケジュールを持っているスタッフのためのセミナーを手に入れたいと思っています。

私が試してみました何:

has_many :future_seminars, -> { future_schedules }, class_name: 'Seminar' 

しかし、問題がある:それはスコープではありませんので、私は、上記の行でfuture_schedulesを渡すことはできません。

has_many :future_seminars, -> { where('schedules.starts_at > ?', Time.now) }, class_name: 'Seminar' 

しかし、それは言う:schedules.starts_atは列ではありません、それはそうです。とにかく、includesのようなものを使ってセミナーのためにschedulesをロードすることができますか?

答えて

2

:よう

何か私はあると思う過去のスケジュールの範囲を入力します。このようなはずです

scope :past, -> { where('ends_at < ?', Time.now) } 
+0

yay !!できます! –

1

パフォーマンスの高い方法が必要な場合は、いくつかのSQLをブレンドする必要があります。また、

has_many :future_seminars, -> { future_seminars }, class_name: 'Seminar' 

セミナーモデルで:スタッフモデルで

scope :future_seminars, -> { joins(:schedules).where("schedules.starts_at >", Time.current) } 

あなたは、おそらくこのような何かを行うことができ

Staff.find(32).seminars. 
       where(Schedule.where("schedules.seminar_id = seminars.id"). 
           where("schedules.starts_at > ?", Time.now).exists) 
関連する問題