有没有比这更有效的方法来加载与列表中的记录相关联的记录?

时间:2015-05-10 01:30:31

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

我有一个模型播放列表和一个模型用户,它们彼此相互拥有,通过连接模型PlaylistUser。

在我的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时,性能会发生巨大变化,因为数据库只需要进行一次查询,而不是数百次查询。

有谁知道如何提高效率?也许我可以以某种方式加载原始查询中的所有相关播放列表?

1 个答案:

答案 0 :(得分:3)

您可以使用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 %>