【发布时间】:2017-07-15 02:05:26
【问题描述】:
目前我们为用户和角色使用两个单独的表。
我正在使用 pundit 进行授权并设计用于身份验证。
在很多地方我都在做current_user.roles 来获取用户的角色。主要在权威政策文件中。
我想在用户登录时将用户角色存储在会话中。这样我就不会每次都查询 db 来获取角色。
任何快速的解决方案将不胜感激?
【问题讨论】:
标签: ruby-on-rails devise ruby-on-rails-5 pundit
目前我们为用户和角色使用两个单独的表。
我正在使用 pundit 进行授权并设计用于身份验证。
在很多地方我都在做current_user.roles 来获取用户的角色。主要在权威政策文件中。
我想在用户登录时将用户角色存储在会话中。这样我就不会每次都查询 db 来获取角色。
任何快速的解决方案将不胜感激?
【问题讨论】:
标签: ruby-on-rails devise ruby-on-rails-5 pundit
由于 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,您可以使用它:在rails_cache_solution 分支或拉取请求中查看我的解决方案变体Rails.cache。
有关详细信息,另请参阅这些文件:
app/controllers/users/sessions_controller.rbspec/controllers/posts_controller_spec.rbapp/policies/post_policy.rbapp/models/user.rbREADME.md
【讨论】: