最后更新时间:2013 年 8 月 29 日 18:54 EST
我定义了以下模块,然后将其包含到我的模型中。我正在使用 rolify gem 给我的用户角色。
module Permissions::Offer
extend ActiveSupport::Concern
included do
# `user` is a context of security
protect do |user, offer|
# Admins can retrieve anything
if user.has_role? :administrator
scope { all }
# ... and view, create, update, or destroy anything
can :view
can :create
can :update
can :destroy
elsif user.present?
# Allow to read any field
can :view
can :create
# Checks offered_by_id keeping possible nil in mind
# Allow sellers to modify/delete their own offers
if offer.try(:offered_by_id) == user.id
can :update
can :destroy
end
else
# Guests can't read the text
cannot :view
end
end
end
end
我正在经历的是,当我执行以下操作时......
respond_with Offer.restrict!(current_user)
它为每个返回的报价查询角色表。无论如何,在请求报价列表时,它是否不会重复提出此请求?我确信我可以缓存响应以避免数据库命中,但我宁愿它也不命中缓存。
如果我打开一个 Rails 控制台并执行以下操作,我会得到相同的结果:
current_user = User.first
Offer.restrict!(current_user).to_a
我已经安装了子弹 gem,看看它是否认为它是一个 N+1 查询,但它没有检测到它。我相信,因为每次创建新的报价实例时都会调用包含的内容,所以它会触发此调用以验证权限。再加上 rolify 不会在任何时间长度内缓存其用户角色检查,这使得这不太理想。我想 rolify 这样做是为了允许即时更改角色,而无需处理清除缓存。到目前为止,我能看到解决这个问题的唯一方法是实现我自己的缓存。