-
Notifications
You must be signed in to change notification settings - Fork 1.4k
type
directive for serializer to control type field with json-api adapter
#1213
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
Conversation
First off, thanks for the PR! My only concern is that So, I guess that leaves two options:
|
There is a test which actually made me to change an approach. So now there's only class method test, which sets _test class variable. And this is used on the class level again, so it'll not interfer with type attribute. |
But I think it would be way smarter to have setting which class name to use (Serializer or Model) AND type directive to set it manually. If you like this idea, I'll add this feature. |
oh good! thanks for looking for that. :-) you have my 👍 @beauby seems to be the JsonApi Adapter expert though, so I'll let him make the final call. |
I added functionality to derive resource type from serializer class, however it broke one test, which I'm not sure is really correct. Depends on standard which I'm not sure in. So the question is how we deal with namespaced models/serializers. Method |
Hi @youroff, you are right, I added the possibility to override the type in a pending PR that got lost somewhere. I am totally up for this PR, I'll review it right away. |
if ActiveModel::Serializer.config.jsonapi_resource_type == :singular | ||
serializer.object.class.model_name.singular | ||
unless serializer.class._type.nil? | ||
serializer.class._type | ||
else |
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.
Avoid unless
with an else
clause. Rewrite as an if
with the positive clause first (https://github.com/bbatsov/ruby-style-guide#no-else-with-unless)
Done, but for namespace case we have to decide what to change: test or code. I'm not sure what json-api says about namespaced models. |
else | ||
serializer.object.class.model_name.plural | ||
if ActiveModel::Serializer.config.type_source == :model |
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 this should be extracted to another PR. I'm generally not in favor of adding too many config options, and with the type
method you introduced, there's virtually no use for this one, except for allowing wildly different workflows for users, which, as well, I'm not too keen on.
Thing is, JSON API explicitly does not say anything about namespaced models. There are PRs in the pipe for better handling of namespaced models, but my personal feeling is that the default should be to remove the namespace for the |
I agree. So I remove namespace for this time to make tests pass? |
Namespaces shouldn't be a problem here, are they? |
They caused one test to fail. Last commit fixes it. If we agree to remove namespaces. |
serializer.object.class.model_name.singular | ||
if serializer.class._type.nil? | ||
if ActiveModel::Serializer.config.type_source == :model | ||
type = serializer.object.class.name.underscore |
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.
We shouldn't modify the behavior here (before it read the type from object.class.model_name
(which is AR-specific, so we may change it later, but not now) to object.class.name
).
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 problem is that weird conversion of namespace comes from plural
or singular
methods. I Thought it would be reasonable to rely on general pluralization applied to string. But I can roll back to previous behavior of course.
What caused the test to fail was that you got the name from the object's class name instead of the AR model name. |
Right, but it doesn't really matter. Anyway we should decide either we leave namespace with separation of some form ( |
http://jsonapi.org/format/#document-member-names |
serializer.object.class.model_name.singular | ||
if serializer.class._type.nil? | ||
if ActiveModel::Serializer.config.type_source == :model | ||
type = serializer.object.class.name.demodulize.underscore |
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'd rather we stick with model_name
, because it might very well be that there are 0 differences, but I have no certainty of that, and would rather change it in a subsequent PR if it makes sense. I get that it makes the pluralizing situation trickier, but it will be refactored soon anyways.
So I roll everything back to |
It's not that we can't leave |
Btw, what |
Ok, so I'll just split this to two PR's? |
That would be nice, yes. |
Well, in general case it'll return ActiveModel::Name populated with class name of the model, but there are some edge cases, that I was not aware of (and I still don't understand the use-case). So probably we need tests for that weird case to make sure that model_name return exactly what we expect. |
Made all corrections mentioned |
@@ -37,6 +37,7 @@ class << self | |||
attr_accessor :_cache_except | |||
attr_accessor :_cache_options | |||
attr_accessor :_cache_digest | |||
attr_accessor :_type |
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 wish there were a better name for this, or a way to signal it is for json_api... resource_type_name
? no need to do anything
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.
n/m, it can/should be removed since class_attribute :_type, instance_writer: false
is added below
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.
- plz remove this accessor as the class_attribute below duplicates the behavior
A few small things and this is ready to merge. 💯 |
@@ -122,6 +127,7 @@ def self.get_serializer_for(klass) | |||
end | |||
|
|||
attr_accessor :object, :root, :meta, :meta_key, :scope | |||
class_attribute :_type, instance_writer: false |
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 can go up near the other class methods
Looks good, last thing to do is rebase it to squash it down to one commit. Lemme know if you want any tips on doing that.. |
If you have some short recipe how to do that, would be nice. Otherwise, I'll google. ;) |
So what I did:
As long as nothing changed since I started this PR, nothing happened... Should I merge to master locally or what? |
This is pretty good
|
you missed updating your local master to the remote on origin :) see above for how I squash.. or if you want we can pair or I can do it.. up to you |
Does it look ok? I expected previous commits to disappear, is that ok that they are still there? |
beautiful! GitHub still knows about the other commits... they're just not part of the PR. It git, you need to work hard to remove things :) |
Add Serializer 'type' directive to control type field, for use by the JsonApi adapter
|
||
def test_explicit_type_value | ||
hash = serializable(@author, serializer: ProfileTypeSerializer, adapter: :json_api).serializable_hash | ||
assert_equal('profile', hash.fetch(:data).fetch(:type)) |
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.
Why using fetch
here instead of brackets?
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.
Better error on failure
B mobile phone
On Oct 4, 2015, at 11:14 AM, Lucas Hosseini [email protected] wrote:
In test/adapter/json_api/resource_type_config_test.rb:
end end
def test_explicit_type_value
hash = serializable(@author, serializer: ProfileTypeSerializer, adapter: :json_api).serializable_hash
Why using fetch here instead of brackets?assert_equal('profile', hash.fetch(:data).fetch(:type))
—
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.
Then why not use it there?
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 at computer now, could be oversight, not important in any case
B mobile phone
On Oct 4, 2015, at 12:33 PM, Lucas Hosseini [email protected] wrote:
In test/adapter/json_api/resource_type_config_test.rb:
end end
def test_explicit_type_value
hash = serializable(@author, serializer: ProfileTypeSerializer, adapter: :json_api).serializable_hash
Then why not use it there?assert_equal('profile', hash.fetch(:data).fetch(:type))
—
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.
Agreed it's not important, but best to remain consistent.
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.
remain consistent
please
This pull-requests implements
type
directive for serializer declaration. Which sets type attribute while using json-api adapter. So it's possible to use ProfileSerializer with User model and set type field to 'profile', like this: