How do I serialize permissions with active_model_serializers? I don't have access to current_user
or the can?
method in models and serializers.
First, to get access to the current_user
in the serializer context, use the new scope feature:
class ApplicationController < ActionController::Base
...
serialization_scope :current_user
end
In case you are instantiating serializers manually, be sure to pass the scope:
model.active_model_serializer.new(model, scope: serialization_scope)
Then inside the serializer, add custom methods to add your own authorization pseudo-attributes, using scope
(the current user) to determine permissions.
If you are using CanCan, you can instantiate your Ability class to access the can?
method:
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
and then define can_update and can_delete as methods in the serializer. Either works, though. –
Immunochemistry can?
method to your model for even better readability — see https://mcmap.net/q/346280/-access-cancan-39-s-can-method-from-a-model. –
Bluish We created a gem that provides this functionality: https://github.com/GroupTalent/active_model_serializers-cancan
I think you can pass anything you want to serialization_scope
so I simply pass the Ability.
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
I can't do otherwise since my abilities are actually based on two variables (not in the example above).
If you still need access to current_user you can simply set an instance variable on Ability.
© 2022 - 2024 — McMap. All rights reserved.