[英]Conditionally eager loading polymorphic associations
我正在嘗試為我的網站上的用戶Feed刪除一些N + 1查詢。 有各種模型與FeedItem模型具有多態關聯
class Event < ActiveRecord::Base
has_many :feed_items, as: :feedable
end
class Tournament < ActiveRecord::Base
has_many :feed_items, as: :feedable
end
class FeedItem < ActiveRecord::Base
belongs_to :feedable, :polymorphic => true
end
用戶模型也涉及用戶具有多種具有不同屬性的錦標賽和事件。 為用戶加載FeedItems時,如何根據FeedItem類型有條件地急切加載嵌套屬性?
我的意思的一個例子(使用squeel DSL):
FeedItem.where{ (feedable_id.in(@user.tournaments.ids}) & feedable_type.eq('Tournament')) |
(feedable_id.in(@user.events.ids) & feedable_type.eq('Event')) }.includes(:feedable => :game)
此查詢嘗試在急切加載錦標賽模型的“游戲”屬性時檢索錦標賽和賽事類型的所有FeedItem。 適用於錦標賽,但在迭代FeedItems時,事件將拋出此屬性不存在的錯誤。
我目前的hack是對每個FeedItem類型執行單獨查詢並將記錄添加到一起。 但是,這會將關聯轉換為我不想做的數組。
有任何想法嗎?
可以為多態關聯預加載嵌套關聯。 您需要向FeedItem
添加兩個關聯:
class FeedItem < ActiveRecord::Base
belongs_to :feedable, :polymorphic => true
belongs_to :event, -> { where(feedable_type: 'Event' ) }, foreign_key: :feedable_id
belongs_to :tournament, -> { where(feedable_type: 'Tournament' ) }, foreign_key: :feedable_id
end
之后,您可以僅為tournament
預加載嵌套關聯:
feeds =
FeedItem.where("
(feedable_id IN (?) AND feedable_type = 'Tournament') OR
(feedable_id IN (?) AND feedable_type = 'Event')", @user.tournament_ids, @user.event_ids).
includes(:feedable, tournament: :game)
現在您可以獲得相關的錦標賽游戲,而無需其他查詢:
feeds.each do |feed|
puts feed.feedable.inspect
puts feed.tournament.game.inspect if feed.feedable_type == "Tournament"
end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.