在rails中,是否存在通过has_many :through
关联进行聚合查询的ActiveRecord方式?
编辑:我正在寻找一个数据库驱动的解决方案,而不是一堆Ruby迭代/修改。
编辑#2:我搞砸了。 Venue模型也是多对多的Show。
例如。想象一下(做作)这样的事情:
# Venue<->Show is many-to-many.
# Show<->Performer is many-to-many.
class Venue < ActiveRecord::Base
has_many :bookings
has_many :shows, through: :bookings
end
# Note "show" here would be "The Lion King," not a specific
# performance on a specific date.
class Show < ActiveRecord::Base
has_many :bookings
has_many :venues, through: :bookings
has_many :engagements
has_many :performers, through: :engagements
end
class Performer < ActiveRecord::Base
has_many :engagements
has_many :shows, through: :engagements
end
# Just a simple join model.
class Engagement < ActiveRecord::Base
belongs_to :show
belongs_to :performer
end
# Also a join model.
class Booking < ActiveRecord::Base
belongs_to :venue
belongs_to :show
end
如何在Venue
上执行查询,该查询返回曾在那里执行的所有Performer
的唯一集合?
谢谢!
答案 0 :(得分:2)
由于您最终需要一组表演者,请从该模型开始。我们知道我们正在寻找一个特定的场地,所以让我们看看我们可以用来达到那个协会。
# Performer
has_many :shows, through: :engagements
# Show
has_many :venues, through: :bookings
宾果!我们可以从表演者到表演场地(Rails将自动找出从参与到节目和预订到场地的连接)。
ActiveRecord支持使用关联名称加入关联(注意:这仅适用于INNER联接):http://guides.rubyonrails.org/active_record_querying.html#using-array-hash-of-named-associations
在阅读该查询指南后,我们知道可以使用Hash语法加入嵌套关联。这让我们
Performer.joins(shows: :venues)
但是我们不能止步于此,因为我们将让所有表演者至少在一个场地至少参加过一次表演(在多场表演,参与,预订或场地中重复任何表演者 - 我们'我会暂时处理这些事情)。为了缩小集合范围,我们必须添加一个WHERE子句。链接指南的第12.3节解释了我们可以向连接表添加哈希条件。 缩小场地看起来像
venue = Venue.find(params[:venue_id])
Performer.joins(shows: :venues).where(venues: {id: venue.id})
现在我们所有表演者都在本场所有演出中演出!但是等等,如果他们玩过多个Show(或Engagement),我们仍然会有重复的表演者。为了删除重复项,我们使用uniq
。
把它们放在一起给了我们
venue = Venue.find(params[:venue_id])
Performer.joins(shows: :venues).where(venues: {id: venue.id}).uniq
答案 1 :(得分:0)
我认为你可以这样做:
venue = Venue.find(?)
# Select only unique Performer ids
unique_performer_ids = Performer.joins(:engagements).where(show_id: venue.show_id).distinct(:id)
# Select unique Performer objects
performers = Performer.where(id: unique_performer_ids)
可以将这两个查询合并为一个使用子查询。