在我的应用程序中,我已经覆盖了一些current_user设计方法。其思想是,如果存在某些cookie,则使用该cookie中的id检查组织,并返回该组织的所有者,而不是常规用户:
def current_user
user = warden.authenticate(scope: :user)
return nil if user.nil?
if user.admin? && cookies.key?('mock_admin_login')
organization = Organization.includes(:creator).find(cookies.encrypted[:mock_admin_login])
return organization.creator
end
user
end
所有操作都是正确的,但是当我查看我的控制台时,我注意到组织查询被多次执行:
缓存组织负载(0.5ms)从“组织”选择“组织”.*。“id”= $1限制$2 ["id",9,“限制”,1]↳
current_user' CACHE User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 [["id", 10]] ↳ app/controllers/concerns/current_methods_overwritten.rb:11:in
current_user的缓存组织负载(0.9ms)从“组织”中选择“组织”.*。“id”= $1限制$2 ["id",9,“限制”,1] app/controllers/concerns/current_methods_overwritten.rb:11:incurrent_user' CACHE User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 [["id", 10]] ↳ app/controllers/concerns/current_methods_overwritten.rb:11:in
current_user的缓存组织负载(0.7ms)从“组织”中选择“组织”.*,其中“组织”= $1限制$2 ["id",9,“限制”,1] app/controllers/concerns/current_methods_overwritten.rb:11:incurrent_user' CACHE User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 [["id", 10]] ↳ app/controllers/concerns/current_methods_overwritten.rb:11:in
current_user的缓存组织负载(0.3ms)从“组织”中选择“组织”.*,其中“组织”= $1限制$2 ["id",9,“限制”,1] app/controllers/concerns/current_methods_overwritten.rb:11:incurrent_user' CACHE User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 [["id", 10]] ↳ app/controllers/concerns/current_methods_overwritten.rb:11:in
current_user的缓存组织负载(0.4ms)从“组织”中选择“组织”.*,其中“组织”= $1限制$2 ["id",9,“限制”,1] app/controllers/concerns/current_methods_overwritten.rb:11:incurrent_user' CACHE User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 [["id", 10]] ↳ app/controllers/concerns/current_methods_overwritten.rb:11:in
current_user的缓存组织负载(2.0ms)从“组织”中选择“组织”.*,其中“组织”= $1限制$2 ["id",9,“限制”,1] app/controllers/concerns/current_methods_overwritten.rb:11:incurrent_user' CACHE User Load (4.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 [["id", 10]] ↳ app/controllers/concerns/current_methods_overwritten.rb:11:in
current_user的缓存组织负载(0.4ms)从“组织”中选择“组织”.*,其中“组织”= $1限制$2 ["id",9,“限制”,1] app/controllers/concerns/current_methods_overwritten.rb:11:incurrent_user' CACHE User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 [["id", 10]] ↳ app/controllers/concerns/current_methods_overwritten.rb:11:in
current_user的缓存组织负载(42.8ms)从“组织”中选择“组织”.*,其中“组织”= $1限制$2 ["id",9,“限制”,1] app/controllers/concerns/current_methods_overwritten.rb:11:incurrent_user' CACHE User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 [["id", 10]] ↳ app/controllers/concerns/current_methods_overwritten.rb:11:in
current_user的缓存组织负载(4.5ms)从“组织”中选择“组织”.*,其中“组织”= $1限制$2 ["id",9,“限制”,1]↳app/controllers/concerns/current_methods_overwritten.rb:11:incurrent_user' CACHE User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 [["id", 10]] ↳ app/controllers/concerns/current_methods_overwritten.rb:11:in
current_user‘
虽然这似乎不是什么大事,但每次调用current_user方法时,服务器都会花费30到40 is来执行此操作。为什么这个查询被调用了那么多次而不是一个,我如何修复它?
发布于 2021-01-04 13:28:51
您需要回溯结果,这样就不会每次调用current_user
时都重新评估结果。
如果您查看设计生成的助手,您可以看到它就是这样做的:
def current_#{mapping}
@current_#{mapping} ||= warden.authenticate(scope: :#{mapping})
end
如果要修复现有方法,则要确保回溯DB调用:
def current_user
@current_user ||= warden.authenticate(scope: :#{mapping})
if @current_user&.admin? && cookies.key?('mock_admin_login')
@current_org || = Organization.includes(:creator)
.find(cookies.encrypted[:mock_admin_login])
@current_user = @current_org.creator
end
@current_user
end
但您确实应该将其实现为一个定制的监狱长策略。
https://stackoverflow.com/questions/65562752
复制相似问题