我希望我能解释清楚。
我担心的是,因为我只是预装@拖车,所以我目前正在对拖车的每一次迭代进行3个新的DB调用。
_notification_form.html.erb (在每个拖车上被呼叫3次)
<% if trailer.movie.tracked?(current_user, "netflix") %>
## do some css stuff on the button to show notification already set
movie.rb:
def tracked?(user, website)
user.notifications.where(movie_id: self.id, website: website).first
end
所以每次渲染一个预告片,我就打3个DB的电话。处理这种情况的正确方法是什么?
发布于 2015-12-09 07:57:52
因为您只检查current_user
的状态,而且每个Trailer
都知道它的movie_id
,所以您只需加载User
的Notification
并检查它们是否为Trailer
‘movie_id
:
tracked = current_user.notifications
tracked.detect { |n| n.movie_id == trailer.movie_id && n.website == 'netflix' }
如果User
可能有大量的Notification
,则可以将所显示页面上的Trailer
的设置限制为仅为Notification
:
tracked = current_user.notifications.where(movie_id: trailers.map(&:movie_id))
加载它,然后检查它,当您决定如何呈现您的按钮。您可以通过创建包含Set
对的[movie_id, website]
来提高效率,这将在固定时间内进行查找。
tracked = Set.new(
current_user.nofications
.where(movie_id: trailers.map(&:movie_id))
.pluck(:movie_id, :website)
)
tracked.include?([trailer.movie_id, 'netflix'])
这一策略对您来说将是快速的,因为它完全适合您正在检查的数据。如果您需要更灵活的方法来将数据库查询降到最低限度,那么请查看如何急切地加载与includes
、preload
和eager_load
的关联。在Rails 3和4中进行紧急加载(预压)的3种方法很好地描述了这些方法之间的差异。这些都是在初始关系加载期间工作的(也就是说,如果您还没有加载任何数据),但是当您已经加载了部分数据(例如,您已经加载了Trailer
s而不是Movies
s或Notification
s )时,您可以使用ActiveRecord::关联::预加载器高效地加载其余的数据。
https://stackoverflow.com/questions/34169208
复制相似问题