首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Rails:通过控制器中的关系预装has_many

Rails:通过控制器中的关系预装has_many
EN

Stack Overflow用户
提问于 2015-12-09 01:28:04
回答 1查看 137关注 0票数 1

我希望我能解释清楚。

  • 用户has_many通知和通过通知的has_many电影。电影has_many预告片。
  • 通知有3列: user_id、movie_id和网站。
  • 在trailers#index上,我呈现@拖车,每个@拖车呈现3x ajax notification_forms (每个表单只是一个按钮,每个“网站”选项都是一个按钮)。当用户单击此按钮时,会发送ajax请求以创建新的通知记录)
  • 我跟踪按下了哪些按钮(通过查找该用户/电影是否存在通知)

我担心的是,因为我只是预装@拖车,所以我目前正在对拖车的每一次迭代进行3个新的DB调用。

_notification_form.html.erb (在每个拖车上被呼叫3次)

代码语言:javascript
运行
复制
<% if trailer.movie.tracked?(current_user, "netflix") %>
   ## do some css stuff on the button to show notification already set

movie.rb:

代码语言:javascript
运行
复制
def tracked?(user, website)
    user.notifications.where(movie_id: self.id, website: website).first
  end

所以每次渲染一个预告片,我就打3个DB的电话。处理这种情况的正确方法是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-09 07:57:52

因为您只检查current_user的状态,而且每个Trailer都知道它的movie_id,所以您只需加载UserNotification并检查它们是否为Trailermovie_id

代码语言:javascript
运行
复制
tracked = current_user.notifications
tracked.detect { |n| n.movie_id == trailer.movie_id && n.website == 'netflix' }

如果User可能有大量的Notification,则可以将所显示页面上的Trailer的设置限制为仅为Notification

代码语言:javascript
运行
复制
tracked = current_user.notifications.where(movie_id: trailers.map(&:movie_id))

加载它,然后检查它,当您决定如何呈现您的按钮。您可以通过创建包含Set对的[movie_id, website]来提高效率,这将在固定时间内进行查找。

代码语言:javascript
运行
复制
tracked = Set.new(
  current_user.nofications
    .where(movie_id: trailers.map(&:movie_id))
    .pluck(:movie_id, :website)
)
tracked.include?([trailer.movie_id, 'netflix'])

这一策略对您来说将是快速的,因为它完全适合您正在检查的数据。如果您需要更灵活的方法来将数据库查询降到最低限度,那么请查看如何急切地加载与includespreloadeager_load的关联。在Rails 3和4中进行紧急加载(预压)的3种方法很好地描述了这些方法之间的差异。这些都是在初始关系加载期间工作的(也就是说,如果您还没有加载任何数据),但是当您已经加载了部分数据(例如,您已经加载了Trailers而不是Moviess或Notifications )时,您可以使用ActiveRecord::关联::预加载器高效地加载其余的数据。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34169208

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档