我有以下型号:
class Piece < ActiveRecord::Base
has_many :instrument_pieces
has_many :instruments, through: :instrument_pieces
end
class Instrument < ActiveRecord::Base
has_many :pieces, through: :instrument_pieces
has_many :instrument_pieces
end
class InstrumentPiece < ActiveRecord::Base
belongs_to :instrument
belongs_to :piece
end
我有以下问题:
Piece
.joins(:instrument_pieces)
.where(instrument_pieces: { instrument_id: search_params[:instruments] } )
.find_each(batch_size: 20) do |p|
search_params[:instruments]
是一个数组。此查询的问题在于它将检索具有任何工具的所有部分,因此如果search_params[:instruments] = ["1","3"]
,查询将返回具有1或3或两者的工具关联的部分。我希望查询只返回其乐器关联包括乐器1和3的乐曲。我已经阅读了文档,但我仍然不确定如何做到这一点...... < / p>
答案 0 :(得分:2)
似乎我想要的是两个查询之间的交集,所以我最终做的是:
queries = []
query = Piece.joins(:instruments)
search_params[:instruments].each do |instrument|
queries << query.where(instruments: {id: instrument})
end
sql_str = ""
queries.each_with_index do |query, i|
sql_str += "#{query.to_sql}"
sql_str += " INTERSECT " if i != queries.length - 1
end
Piece.find_by_sql(sql_str).each do |p|
非常难看,但ActiveRecord还不支持INTERSECT。我想是等待ActiveRecord 5的时候了。
答案 1 :(得分:1)
您可以使用where子句链接来实现此目的。尝试:
query = Piece.joins(:instrument_pieces)
search_params[:instruments].each do |instrument|
query = query.where(instrument_pieces: { instrument_id: instrument } )
end
query.find_each(batch_size: 20) do |p|
或其他版本
query = Piece.joins(:instruments)
search_params[:instruments].each do |instrument|
query = query.where(instrument_id: instrument)
end
query.find_each(batch_size: 20) do |p|