Rails has_many :通过和 N+1
Rails has_many :through and N+1
我有两个关联模型:聊天和用户通过会员模型
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)
如何优化和加速这些查询?
我认为这里的问题是:
您在联接中包括 :memberships
,因此如果您调用 chat.memberships
,它将使用存储在内存中的成员资格。
但是您正在调用 chat.memberships.order('id ASC')
,这是一个 sql 查询,Rails 尚未缓存,因此必须调用。
简单的解决方案是按 Ruby 排序而不是 SQL:
chat.memberships.sort_by(&:id)
我有两个关联模型:聊天和用户通过会员模型
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)
如何优化和加速这些查询?
我认为这里的问题是:
您在联接中包括 :memberships
,因此如果您调用 chat.memberships
,它将使用存储在内存中的成员资格。
但是您正在调用 chat.memberships.order('id ASC')
,这是一个 sql 查询,Rails 尚未缓存,因此必须调用。
简单的解决方案是按 Ruby 排序而不是 SQL:
chat.memberships.sort_by(&:id)