-
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
Fix fields
option to restrict relationships as well.
#1297
Conversation
6d5a9a0
to
f6b2cdc
Compare
f6b2cdc
to
13ef8fe
Compare
@@ -174,7 +174,10 @@ def relationship_value_for(serializer, options = {}) | |||
end | |||
|
|||
def relationships_for(serializer) | |||
serializer.associations.each_with_object({}) do |association, hash| | |||
resource_type = resource_identifier_type_for(serializer) | |||
requested_associations = fieldset.try(:fields_for, resource_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.
in what situation does a fieldset not have fields_for?
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 guess, I'd like some docs here explaining why this is happening :-)
I'll be ok with merging once that's done. :-)
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.
When fieldset is not initialized (which currently happens when the fields
option is not provided).
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.
Docs explaining why what is happening?
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 situation you just described with fieldset.
It's important to have docs like this when someone new starts working on the json api adapter.
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.
also, that's not an excuse to get out of writing docs.
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.
Code comments are not docs in my opinion. Maybe we're not talking about the same thing?
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.
perhaps.
I'm not meaning to write something that just anyone would look at. but a reminder of what is happening in the code, possibly the scenarios in which certain control flows are followed - so that even the author of the code can have an easier time re-familiarizing with the code 1+ years from when the code was written.
node of that is intended to be in the public documentation that would end up on ruby-doc.org or 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.
Then I still disagree. Code that needs explanations is just bad code in my opinion. If you think this bit is obscure, then I'd rather we work to make it less obscure than write a comment to explain it.
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.
Um.. I don't understand the change from the code :)
@@ -21,7 +21,7 @@ def fields_for(type) | |||
|
|||
def parsed_fields | |||
if raw_fields.is_a?(Hash) | |||
raw_fields.inject({}) { |h, (k, v)| h[k.to_sym] = v.map(&:to_sym); h } | |||
raw_fields.each_with_object({}) { |(k, v), h| h[k.to_sym] = v.map(&:to_sym) } |
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 (isomorphic) change is not necessary for this PR, but it makes the code slightly cleaner.
Fix `fields` option to restrict relationships as well.
@beauby @NullVoxPopuli can you help me understand why the order of the fieldset was changed? Also, for a bit I thought the - fields = options.delete(:fields)
- if fields
- @fieldset = ActiveModel::Serializer::Fieldset.new(fields)
- else
- @fieldset = options[:fieldset]
- end
+ @fieldset = options[:fieldset] || ActiveModel::Serializer::Fieldset.new(options.delete(:fields)) Is really the same as - fields = options.delete(:fields)
- if fields
- @fieldset = ActiveModel::Serializer::Fieldset.new(fields)
- else
- @fieldset = options[:fieldset]
- end
+ @fieldset = options[:fieldset]
+ if @fieldset.nil?
+ fields = options.delete(:fields))
+ @fieldset = ActiveModel::Serializer::Fieldset.new(fields || {}) # where the fieldset initializer was modified as paraphrased here
+ end |
resource_type = resource_identifier_type_for(serializer) | ||
requested_associations = fieldset.fields_for(resource_type) || '*' | ||
include_tree = IncludeTree.from_include_args(requested_associations) | ||
serializer.associations(include_tree).each_with_object({}) do |association, hash| |
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.
In words, what does this diff do?
- serializer.associations.each_with_object({}) do |association, hash|
+ resource_type = resource_identifier_type_for(serializer)
+ requested_associations = fieldset.fields_for(resource_type) || '*'
+ include_tree = IncludeTree.from_include_args(requested_associations)
+ serializer.associations(include_tree).each_with_object({}) do |association, hash|
It's supposed to somehow remove associations somehow?
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.
It filters out associations not present in the fieldset of the resource (unless no fieldset has been provided for that resource).
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.
maybe it's just the method and variable names. I can be pretty literal-minded and it looks like whereas before we would iterate over the associations, now we ask the serializer what it's type
ask the fieldset for its fields, or use *
, which guess means ALL, the include_tree is something that is passed to associations?
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.
Exactly. The IncludeTree
is probably not a perfect name. It is basically a structure that describes a labelled tree in such a way that you can query it using wildcards.
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.
serializer.associations(include_tree)
this filters associations
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 I guess this means that an explanation needs to be in code comments. :-)
Would like to promote discussion of optimizing code to not make me think: #1297 (comment) 😄 |
@bf4 Any suggestion welcome. |
The current implementation breaks the JSON API spec in the way it handles sparse fieldsets, since the definition of fields is: