【发布时间】:2012-07-25 23:24:59
【问题描述】:
如何使用 active_model_serializers 序列化权限?我无权访问模型和序列化程序中的current_user 或can? 方法。
【问题讨论】:
标签: ruby-on-rails cancan activemodel active-model-serializers
如何使用 active_model_serializers 序列化权限?我无权访问模型和序列化程序中的current_user 或can? 方法。
【问题讨论】:
标签: ruby-on-rails cancan activemodel active-model-serializers
首先,要在序列化程序上下文中访问current_user,请使用新的范围功能:
class ApplicationController < ActionController::Base
...
serialization_scope :current_user
end
如果您手动实例化序列化程序,请确保传递范围:
model.active_model_serializer.new(model, scope: serialization_scope)
然后在序列化器内部,添加自定义方法来添加自己的授权伪属性,使用scope(当前用户)来确定权限。
如果你使用 CanCan,你可以实例化你的 Ability 类来访问can? 方法:
attributes :can_update, :can_delete
def can_update
# `scope` is current_user
Ability.new(scope).can?(:update, object)
end
def can_delete
Ability.new(scope).can?(:delete, object)
end
【讨论】:
attributes :can_update, :can_delete,然后将can_update 和can_delete 定义为序列化程序中的方法。不过,两者都可以。
can? 方法委托给您的模型以获得更好的可读性——请参阅stackoverflow.com/a/3293522/797639。
我们创建了一个提供此功能的 gem:https://github.com/GroupTalent/active_model_serializers-cancan
【讨论】:
我认为你可以将任何你想传递给serialization_scope,所以我只是传递能力。
class ApplicationController < ActionController::Base
...
serialization_scope :current_ability
def current_ability
@current_ability ||= Ability.new(current_user)
end
end
class CommentSerializer < ActiveModel::Serializer
attributes :id, :content, :created_at, :can_update
def can_update
scope.can?(:update, object)
end
end
我不能这样做,因为我的能力实际上是基于两个变量(不在上面的示例中)。
如果您仍然需要访问 current_user,您可以简单地在 Ability 上设置一个实例变量。
【讨论】: