【问题标题】:has_many doesn't fetch all when includes(:association).where("association.something = ?", value)has_many 不获取所有时 includes(:association).where("association.something = ?", value)
【发布时间】:2014-10-21 19:10:58
【问题描述】:

我需要你的帮助:

我有三个模型:

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 个录音机:

 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\">
]>"

请帮忙! :)

【问题讨论】:

  • 只有一个 PhonogramInstrument 符合 phonogram_id 14 和 filter_id 30 的条件,所以 ilrein 的回答是对的。
  • 但是 phonogram #14 有 7 个 PhonogramInstrument,而我的 ActiveRecord::Associations::CollectionProxy 与我的 phonogram #14 和 1 PhonogramInstrument 一起出现
  • 你能在 Rails 控制器中执行你的代码@phonograms.includes(:phonogram_instruments).where("phonogram_instruments.filter_id = ?", 30) 吗?并在您的数据库命令窗口上运行由 rails 生成的 SQL。您可以在您的问题上发布 SQL 和结果。

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


【解决方案1】:

尝试joins 而不是includes

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

在此处查看预加载部分

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

【讨论】:

  • 我试过了。我有一个错误,因为以前的@phonograms 包含其他关联
【解决方案2】:

您没有明确提出问题。问题是什么?我看到您表示 Phonogram #14 有 7 个与之关联的对象,而 Phonogram #1 有 1 个与之关联的对象(其中过滤器 ID 设置为 30)。

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

【讨论】:

  • 两个录音对象是一样的#14
【解决方案3】:

完成!

我的错误是因为我之前的列表包含了与 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)

有效!谢谢大家!

【讨论】:

    猜你喜欢
    • 2022-07-08
    • 2011-12-02
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多