如何自定义设计以在会话中存储用户角色信息?
How to customise devise to store user role information in session?
目前我们为用户和角色使用两个单独的 table。
我正在使用 pundit 进行授权并使用 devise 进行身份验证。
在很多地方我都在current_user.roles
获取用户的角色。主要在权威政策文件中。
我想在用户登录时将用户角色存储在会话中。这样我就不会每次都查询数据库来获取角色。
任何快速解决方案将不胜感激?
由于 Pundit 没有选项,要传递 session
或其他参数,除了 current_user
并检查 entity
,您可以改用 Rails.cache
:
# app/models/user.rb
class User < ActiveRecord::Base
# ...
def cached_roles
Rails.cache.fetch "user.#{self.id}.roles" do
roles.pluck(:name)
end
end
def clear_cached_roles
Rails.cache.delete "user.#{self.id}.roles"
end
end
# app/policies/post_policy.rb
class PostPolicy < ApplicationPolicy
# ...
def admin?
user.cached_roles.include? 'admin'
end
def reader?
user.cached_roles.include? 'reader'
end
end
要让 Devise 缓存当前角色,您需要覆盖 Devise 的 session_controller
# app/controllers/users/sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
def create
super
current_user.cached_roles
end
def destroy
current_user.clear_cached_roles
super
end
end
我创建了这个 demo rails application, you can play with it: see my solution variant with Rails.cache
in rails_cache_solution 分支或在拉取请求中。
另请参阅这些文件以获取更多详细信息:
app/controllers/users/sessions_controller.rb
spec/controllers/posts_controller_spec.rb
app/policies/post_policy.rb
app/models/user.rb
README.md
目前我们为用户和角色使用两个单独的 table。
我正在使用 pundit 进行授权并使用 devise 进行身份验证。
在很多地方我都在current_user.roles
获取用户的角色。主要在权威政策文件中。
我想在用户登录时将用户角色存储在会话中。这样我就不会每次都查询数据库来获取角色。
任何快速解决方案将不胜感激?
由于 Pundit 没有选项,要传递 session
或其他参数,除了 current_user
并检查 entity
,您可以改用 Rails.cache
:
# app/models/user.rb
class User < ActiveRecord::Base
# ...
def cached_roles
Rails.cache.fetch "user.#{self.id}.roles" do
roles.pluck(:name)
end
end
def clear_cached_roles
Rails.cache.delete "user.#{self.id}.roles"
end
end
# app/policies/post_policy.rb
class PostPolicy < ApplicationPolicy
# ...
def admin?
user.cached_roles.include? 'admin'
end
def reader?
user.cached_roles.include? 'reader'
end
end
要让 Devise 缓存当前角色,您需要覆盖 Devise 的 session_controller
# app/controllers/users/sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
def create
super
current_user.cached_roles
end
def destroy
current_user.clear_cached_roles
super
end
end
我创建了这个 demo rails application, you can play with it: see my solution variant with Rails.cache
in rails_cache_solution 分支或在拉取请求中。
另请参阅这些文件以获取更多详细信息:
app/controllers/users/sessions_controller.rb
spec/controllers/posts_controller_spec.rb
app/policies/post_policy.rb
app/models/user.rb
README.md