包含(:association).where(“association.something =?”,value)时has_many不会获取所有内容

时间:2014-08-28 03:01:44

标签: ruby-on-rails ruby-on-rails-4 has-many-through has-many

我需要你的帮助:

我有三种模式:

Phonogram has_many PhonogramInstrument:

class Phonogram < ActiveRecord::Base
  #... things
  has_many :phonogram_instruments, source: :filter, dependent: :destroy, inverse_of: :phonogram
  has_many :instruments, source: :filter, through: :phonogram_instruments
end

PhonogramInstrument belongs_to过滤器:

class PhonogramInstrument < ActiveRecord::Base
  belongs_to :phonogram
  belongs_to :filter
end

和过滤器:

class Filter < ActiveRecord::Base

end

所以,我需要获取所有具有filter_id 30的录音制品,例如:

@phonograms = @phonograms.includes(:phonogram_instruments).where("phonogram_instruments.filter_id = ?", 30)

用一个对象取出一个列表(正是我所期待的):

=> [#<Phonogram id: 14, title: "Test", version_title: "", notes: nil, isrc: "BR3BD1300003", release_date: "2013-02-01", created_at: "2014-02-23 16:54:24", updated_at: "2014-08-27 03:19:08">]

...但如果我拿这个物体并展示它的乐器:

    @phonograms.first.phonogram_instruments.inspect
=> #<ActiveRecord::Associations::CollectionProxy [#<PhonogramInstrument id: 51, phonogram_id: 14, filter_id: 30, created_at: "2014-08-27 07:01:27", updated_at: "2014-08-27 07:01:27">]>

但是在这个录音制品中我有7个PhonogramInstruments:

 Phonogram.find(14).phonogram_instruments.inspect
=> "#<ActiveRecord::Associations::CollectionProxy [
#<PhonogramInstrument id: 25, phonogram_id: 14, filter_id: 25, created_at: \"2014-06-04 06:11:14\", updated_at: \"2014-06-04 06:11:14\">, 
#<PhonogramInstrument id: 26, phonogram_id: 14, filter_id: 26, created_at: \"2014-06-04 06:11:14\", updated_at: \"2014-06-04 06:11:14\">, 
#<PhonogramInstrument id: 48, phonogram_id: 14, filter_id: 49, created_at: \"2014-08-27 03:19:07\", updated_at: \"2014-08-27 03:19:07\">, 
#<PhonogramInstrument id: 49, phonogram_id: 14, filter_id: 50, created_at: \"2014-08-27 03:19:08\", updated_at: \"2014-08-27 03:19:08\">, 
#<PhonogramInstrument id: 50, phonogram_id: 14, filter_id: 29, created_at: \"2014-08-27 07:01:27\", updated_at: \"2014-08-27 07:01:27\">,
#<PhonogramInstrument id: 51, phonogram_id: 14, filter_id: 30, created_at: \"2014-08-27 07:01:27\", updated_at: \"2014-08-27 07:01:27\">, 
#<PhonogramInstrument id: 52, phonogram_id: 14, filter_id: 31, created_at: \"2014-08-27 07:01:27\", updated_at: \"2014-08-27 07:01:27\">
]>"

请帮忙! :)

3 个答案:

答案 0 :(得分:4)

尝试使用joins代替includes

  @phonograms = Phonogram.joins(:phonogram_instruments).where("phonogram_instruments.filter_id = ?", 30)

请参阅此处预加载部分

http://blog.arkency.com/2013/12/rails4-preloading/

答案 1 :(得分:2)

你没有明确提出问题。问题是什么?我看到你指出Phonogram#14有7个与之关联的对象,而Phonogram#1有1个与之关联的对象(滤镜ID设置为30)。

一切似乎都按预期进行......

答案 2 :(得分:0)

完成!

我的错误是因为我之前的列表包括与includes()的其他关联:

@phonograms = @phonograms.includes([:artists, :partners, :labels, :albums]).where(...)

当我尝试使用

@phonograms.joins("phonogram_instruments").where(...)

...在我的查询中独自浮动的单词“phonogram_instruments”附近出现错误。

所以,我把手动LEFT OUTER JOIN放在我的查询上:

@phonograms = @phonograms.joins("LEFT OUTER JOIN \"#{listed_filter.type}\" \"#{listed_filter.type}_phonograms\" ON \"#{listed_filter.type}_phonograms\".\"phonogram_id\" = \"phonograms\".\"id\"").where("#{listed_filter.type}_phonograms.filter_id = ?", listed_filter.id)

有效!谢谢大家!