Rails has_many:通过和N + 1

时间:2015-01-09 14:23:35

标签: ruby-on-rails activerecord

我有两个相关的模型:聊天和用户通过会员资格模型

class Chat < ActiveRecord::Base
 has_many :memberships
 has_many :members, through: :memberships
end

class Membership < ActiveRecord::Base
 belongs_to :chat
 belongs_to :member, class_name: "User", foreign_key: 'user_id'
end

在控制器中,我检索这样的记录:

@chats = Chat.joins(:memberships).includes([:owner, :memberships=>:member])
.where("chats.owner_id = ? OR memberships.user_id = ?", current_user.id, current_user.id)

在视图中我用JBuilder显示聊天内容:

json.extract! @chat, :id
   json.members @chat.memberships.order('id ASC') do |membership|
     json.name membership.member.name
   end
end

但是Rails会生成大量的数据库查询,并且视图渲染需要很长时间:

Completed 200 OK in 1597ms (Views: 1393.8ms | ActiveRecord: 150.8ms)

如何优化和加快这些查询?

1 个答案:

答案 0 :(得分:4)

我认为这里的问题是:

您在联接中包含:memberships,因此如果您致电chat.memberships,它将使用存储在内存中的成员资格。

但是你正在调用chat.memberships.order('id ASC')这是一个sql查询,Rails没有缓存,所以必须调用。

简单的解决方案是在Ruby而不是SQL中进行排序:

chat.memberships.sort_by(&:id)