Dav*_*ite 15 activerecord ruby-on-rails eager-loading devise ruby-on-rails-3
我在我的Rails应用程序中使用Devise进行身份验证.我想在我的一些控制器中加载一些用户相关模型.像这样的东西:
class TeamsController < ApplicationController
def show
@team = Team.includes(:members).find params[:id]
current_user.includes(:saved_listings)
# normal controller stuff
end
end
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
Thi*_*ilo 23
我遇到了同样的问题,尽管每个人都说没有必要这样做,但我发现就像你一样.这对我有用:
# in application_controller.rb:
def current_user
@current_user ||= super && User.includes(:saved_listings).find(@current_user.id)
end
Run Code Online (Sandbox Code Playgroud)
请注意,这将加载所有控制器中的关联.对于我的用例,这正是我需要的.如果你真的只想在某些控制器中使用它,你将不得不进一步调整它.
这也会调用User.find两次,但是查询缓存不应该是一个问题,并且因为它可以防止大量额外的数据库命中,所以它仍然是性能提升.
xHo*_*uet 11
我想添加我认为更好的解决方案。如评论中所述,现有解决方案可能会根据find请求两次访问您的数据库。相反,我们可以ActiveRecord::Associations::Preloader利用 Rails 解决加载关联的工作:
def current_user
@current_user ||= super.tap do |user|
::ActiveRecord::Associations::Preloader.new.preload(user, :saved_listings)
end
end
Run Code Online (Sandbox Code Playgroud)
这将重用内存中的现有模型,而不是再次连接和查询整个表。
Vik*_*ary 10
serialize_from_session在User模型中覆盖.
class User
devise :database_authenticatable
def self.serialize_from_session key, salt
record = where(id: key).eager_load(:saved_listings, roles: :accounts).first
record if record && record.authenticatable_salt == salt
end
end
Run Code Online (Sandbox Code Playgroud)
但是,这将迫切需要加载所有请求.
| 归档时间: |
|
| 查看次数: |
5586 次 |
| 最近记录: |