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.

- 30,333
- 19
- 121
- 170
3 Answers
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

- 30,333
- 19
- 121
- 170
-
I don't understand -- did you answer your own question right away? – Jesse Wolgamott Jul 26 '12 at 01:51
-
2Yes, I did – see [this article](http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/). I wanted this piece of knowledge preserved, but found it too trivial/specialized to post on my blog, so I posted it here, Q&A style. – Jo Liss Jul 26 '12 at 09:05
-
1@JoLiss As an alternative to the "super.merge" style, you can say `attributes :can_update, :can_delete` and then define can_update and can_delete as methods in the serializer. Either works, though. – tee Jul 27 '12 at 04:59
-
You can also delegate the `can?` method to your model for even better readability — see http://stackoverflow.com/a/3293522/797639. – pierrea Oct 16 '14 at 10:21
We created a gem that provides this functionality: https://github.com/GroupTalent/active_model_serializers-cancan

- 7,777
- 7
- 48
- 53
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.

- 21
- 1
- 1