-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add serialization_scope example #1252
Conversation
This is important but I find the example confusing. |
def index | ||
render json: User.new(id: 1, name: 'Pete', admin: false), serializer: AdminUserSerializer, adapter: :json_api | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@beauby how could the example be better. I was lazy and just cribbed the test, but maybe you have something in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bf4: Could you fill me in on what exactly we are testing here? It feels like we're making sure we can override the scope?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not testing, documenting usage (no overriding)
B mobile phone
On Oct 8, 2015, at 5:27 PM, Lucas Hosseini [email protected] wrote:
In README.md:
+
+ +In order to do this, all we need to do is declare the
serialization_scope: + +
ruby
+class SomeController < ActionController::Base
- serialization_scope :current_admin
- def current_admin
- User.new(id: 2, name: 'Bob', admin: true)
- end
- def index
- render json: User.new(id: 1, name: 'Pete', admin: false), serializer: AdminUserSerializer, adapter: :json_api
- end
+end
@bf4: Could you fill me in on what exactly we are testing here? It feels like we're making sure we can override the scope?—
Reply to this email directly or view it on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha right, I was a bit confused. What do you think about:
class PostSerializer < AMS
attributes :title, :body, :can_edit?
def can_edit?
scope.admin?
end
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, wanna edit? I'm busy for a while
ref: #1281 (comment) |
bb4383c
to
6b6aed8
Compare
Updated, but the example needs help from someone who's used the feature |
6b6aed8
to
4000b92
Compare
@rails-api/ams any thoughts on this? |
I think the example is good. If there are no other objects, I'll merge it |
|
||
In the usual case, the serializer instance method has the same name as the controller method. | ||
e.g. `serializer.current_user` calls `controller.current_user`. The method's name | ||
will always be the `serialization_scope` defined in the controller, but may be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sentence is a bit hard to understand (at least for me). What is "the serialization_scope
"? The parameter to the (class) method call serialization_scope :foo
? (i.e. :foo
in this case) I guess not as you talk about the controller.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, here's my dirty secret: this part of the code is a bit hard to understand.. by putting something in master, it forces a few more questions and I'm hoping maybe someone else can may it clearer :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 I'm on board with that.
Found another related issue: #741 It references an example setting serialization_scope to
|
4000b92
to
c36271a
Compare
| options | `Serializer#scope` | method definition | | ||
|-------- | ------------------| | ||
| `scope: :current_user, scope_name: :current_user` | `:current_user` | `Serializer#current_user` calls `controller.current_user` | ||
| `scope: :current_admin, scope_name: :current_admin` | `:current_admin` | `Serializer#current_admin` calls `controller.current_admin` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's bugs hiding here
I updated with some more thought and comparison to 0.9. I like the examples better, and now understand the discussion of 'authorization context' I think we lost the usage of the e.g. Also, looks like the serializer could break if |
c36271a
to
619807c
Compare
I think in general this documentation is good and a well needed addition :) 👍 @bf4 However I also noticed some problems trying to pass in |
Feel free to make a pr into my branch B mobile phone
|
619807c
to
fd544ad
Compare
@buren I may have found the bug |
|
||
In the controller, the scope/scope_name options are equal to | ||
the [`serialization_scope`method](https://github.com/rails-api/active_model_serializers/blob/d02cd30fe55a3ea85e1d351b6e039620903c1871/lib/action_controller/serialization.rb#L13-L20), | ||
which is `:current_user`, by default. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The controller defineds
class_attribute :_serialization_scope
self._serialization_scope = :current_user
def serialization_scope
send(_serialization_scope) if _serialization_scope &&
respond_to?(_serialization_scope, true)
end
def serialization_scope(scope)
self._serialization_scope = scope
end
end
then serialization resource calls
serializable_resource.serialization_scope ||= serialization_scope
serializable_resource.serialization_scope_name = _serialization_scope
notice that serialization_scope
is actually the return value of sending the _serialization_scope
method in the controller (if that method exists).
Those two setters correspond to the serializar options scope
and scope_name
respectively, which may also be passed in as params to render
fd544ad
to
002292a
Compare
get :render_post_with_no_scope | ||
end | ||
assert_match exception_matcher, exception.message | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug in Serializer._serializer_instance_methods
is causing the scoped method to sometimes be available to read_attribute_for_serialization
and sometime not, since the public instance methods are cached once, but they change with scopes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the fix for this bug for another PR?
47669f5
to
12ce44d
Compare
|
||
# scope comments to those created_by the current user | ||
has_many :comments do | ||
object.comments.where(created_by: current_user) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is same as object.comments.where(created_by: scope)
12ce44d
to
5dd6f34
Compare
present and the controller responds to `scope_name`. | ||
|
||
Thus, in a serializer, the controller provides `current_user` as the | ||
current authorization scope when you call `render :json`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is currently a bug that prevents you from passing scope
or scope_name
via render options.
5dd6f34
to
2958fbf
Compare
@bf4 wow great work! Impressed that you found the "special" Rails 4 behaviour 👍 |
@buren well, it failed tests.. so.. |
👍 |
2958fbf
to
364b8ab
Compare
NoMethodError is current_user is nil, so nil.admin? NameError is a superclass of NoMethodError (which Rails 4.0 won't allow) and means current_user might not be defined
364b8ab
to
1b2f5ec
Compare
[DOCS/TEST] Add serialization_scope example
ref #1245
serialization_scope nil
scope methods existing on the serializer #1509