質問

I have an app in Rails 3.0.1 . There is a table called Books which has many lists. I have conditional association with lists depending on whether they are good lists or bad lists.

#Book.rb
has_many :lists
has_many :good_lists, :foreign_key => 'book_id', :class_name => "List", :conditions => {:id => List.good_list_ids}
has_many :bad_lists, :foreign_key => 'book_id', :class_name => "List", :conditions => {:id => List.bad_list_ids}

Currently the conditions are cached when the app is started but I want it to be dynamic as the good_list_ids and bad_list_ids can change runtime. I want to be able to find books that are associated with both lists by chaining joins. For eg if good_lists_ids = [1,2,3] and bad_lists_ids = [4,5,6]. I would like to get books that are associated with at least one good_list_ids and at least one bad_list_ids.

Book.joins(:good_lists).joins(:bad_lists)

I know it can be done by applying filters after fetching the records from db. But is there a way to do this only in sql using AREL?

役に立ちましたか?

解決

I agree with @zapico - use scopes. And you must use Lambda because List.good_list_ids and List.bad_list_ids are dynamic.

#Book.rb
has_many :lists    
scope :good_lists, -> { joins(:lists).where('lists.id IN (?)', List.good_list_ids) }
scope :bad_lists, -> { joins(:lists).where('lists.id IN (?)', List.bad_list_ids) }

Update

now you can get books which are in these lists

# in bad list
Book.bad_lists
# in good list
Book.good_lists
# in both lists (this is intersection! for these lists)
Book.bad_lists.good_lists

If you would like to have records belong to good_list OR bad_list then it seems to me the easiest way is

# join arrays
scope :good_bad_lists, -> { joins(:lists).where('lists.id IN (?)', List.good_list_ids | List.bad_list_ids) }
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top