【问题标题】:Is there a more efficient way than this to load records associated with records in a list?有没有比这更有效的方法来加载与列表中的记录关联的记录?
【发布时间】:2015-07-20 17:22:40
【问题描述】:

我有一个模型播放列表和一个模型用户,两者都有_many,通过一个连接模型播放列表用户。

在我的playlists#show 操作中,我想打印一个播放列表的所有用户的列表,以及与每个用户关联的前两个播放列表。

现在这就是我所拥有的:

播放列表/show.html.erb

<% @playlist = Playlist.find(params[:id]) %>
<% @playlist.users.each do |user| %>
  <%= user.name %>
  <%= user.playlists.first.name %>
  <%= user.playlists.second.name %>
<% end %>

模型

class User < ActiveRecord::Base
  has_many :playlist_users
  has_many :playlists, :through => :playlist_users
end

class PlaylistUser < ActiveRecord::Base
  belongs_to :playlist
  belongs_to :user
end

class Playlist < ActiveRecord::Base
  has_many :playlist_users
  has_many :users, :through => :playlist_users
end

但是当我删除user.playlists 行并仅打印出user.name 时,性能发生了巨大变化,因为这样数据库只需进行一次查询,而不是数百次。

有谁知道提高效率的方法吗?也许我可以在原始查询中加载所有关联的播放列表?

【问题讨论】:

标签: sql ruby-on-rails ruby database performance


【解决方案1】:

您可以使用includes 方法告诉Rails 预先加载一个查询的关联记录。

从数据库加载是控制器的职责,不应发生在视图中。因此,将以下内容添加到您的控制器中:

playlist = Playlist.find(params[:id])
@users = playlist.users.includes(:playlists)

并更改您的视图以仅遍历用户数组:

<% @users.each do |user| %>
  <%= user.name %>
  <%= user.playlists.first.name %>
  <%= user.playlists.second.name %>
<% end %>

【讨论】:

  • 有没有办法在原始查询中对包含的表进行排序?例如,如果我想通过order(:song_count) 订购user.playlists
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多