-
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
Include option for associations in serializers #1333
Comments
Not at the moment, but there is discussion about it. |
Thanks for the quick response! Fwiw, I think having them included by default would make the upgrade path from 0.8 and 0.9 to 0.10 much easier and more backwards compatible (and not needing to include associations every time or refactor code to prevent repetition). |
@oyeanuj, PR #1127 does exactly what you're asking, but unfortunately have been merged the 21st of September, only 5 days after 0.10.0-rc3 was released. |
@iMacTia Thats really good to know, thank you for that. Couple of questions with your PR:
@joaomdmoura If I can add to the rc4 question :) - when is the 0.10 final release roughly aimed for? Thanks again! |
@oyeanuj unfortunately I can't take the merit for that PR because is all @NullVoxPopuli work :) |
|
@beauby Thanks for the context, I was missing that. In that case, it would be really helpful to have Thanks again for your work on this library! |
I'll try to issue a PR that adds support for |
@beauby thank you, appreciate it! |
For JSON API, there shouldn't be a need for only exclude, since it's always opt-in. Otherwise, it would be an argument to the include tree thingy, right? |
@bf4 Having the only/except also is allowing for major backwards compatibility for those upgrading from 0.8.x and 0.9.x. When dealing with associations in serializers, |
You're right. I keep mixing up internal vs external options. Internal like here would work well with serilization scopes and requested attributes B mobile phone
|
@bf4 There will be some discussion about priorities of the options, but my current thought is "if an explicit |
Agreed B mobile phone
|
@beauby Did this ever make it in to 0.10 and documented? |
Is anyone working on adding the 'include: true' option to associations? Would be nice to couple 'include' with 'if' so we can move inclusion logic to the serializers. Also 'include' sounds ambiguous as all attributes/associations are included by default (unless they are nested). Perhaps 'always_include' or something. |
I would like to 👍 +1 on this one and to trigger the "Team Discussion" needed to progress on this :) I understand the concerns around this feature, as @bf4 already pointed out:
render json: post, include: [:metrics, :media, :publishes, :author],
fields: { media: [:title], publishers: (PublisherSerializer._attributes - :publisher_bio) }.
And @NullVoxPopuli added:
So here we are, do you think we can have a chat about it and try to find an implementation that would suite everyone? I made a PR in the past to add this capability: ==== Discussion time! ==== First of all, I would like to reply to @bf4 because this looks to me like the most important decision in this matter. I had a quick read about the jsonapi semantics and I think this is the paragraph concerning our case: http://jsonapi.org/format/#fetching-includes
My interpretation is that having default nested resources and don't allowing a customisation through the The solution to this (edge?) case is to allow people to specify at serialiser level which associations will ALWAYS be included, regardless of the context. I really think we should all agree on this before going forward, would love to hear your thought on this :) |
@iMacTia thanks for posting your code! Some questions I have:
|
Very interesting questions, I asked myself the same and here is my personal opinion:
Here is an example for point 2 (including a 2-level nesting): # post_serializer.rb
default_includes :media, :author
has_many :media, only: [:title]
has_one :author # author_serializer.rb
default_includes :website
has_one :website, only: [:url] # posts_controller.rb
render @post would be the equivalent of # post_serializer.rb
has_many :media # not sure if `only: [:title]` should go here as well
has_one :author # author_serializer.rb
has_one :website # not sure if `only: [:url]` should go here as well # posts_controller.rb
render json: @post, include: [:media, author: [:website]],
fields: { media: [:title], author: { website: [:url] } } |
So happy to see this issue come alive again! Thanks @iMacTia @NullVoxPopuli :) Couple of questions which I'd like clarified -
The changes discussed seem to be really a convenience for the purposes of coding what the defaults should be for different objects - one that shouldn't be affected by the adapter itself. Sorry, if I am misunderstanding some part of the conversation here - would love to understand what I am missing.
|
I like this idea, maybe more than having an @oyeanuj, something to keep in mind: 0.8, 0.9, and 0.10 have all been rewrites :-( we're getting there with 0.10. progress is just slow. :-( |
@oyeanuj I'm sorry for not being clear enough on this point, but since the render Regarding the |
+1 for default_includes, it could be used for conditionally including associations too. WIth the include: true option, the next feature request will be include: :is_current_user? etc. It is also intuitive that default_includes will be merged with the include param on the render call. |
@tommiller1 not sure what do you mean by
could you provide an example :)? @NullVoxPopuli it looks like this |
If you look at the ':if' keyword in ams, it supports blocks and lambdas to allow conditions. Similarly a ':default' keyword would also be expected to support all that. Anyway nevermind, the 'default_includes' is probably the most elegant and unobtrusive way of adding this functionality. Thanks for working on it, hope the creators will accept your pr. |
Thanks! Will do my best to get something done to have this feature in place as soon as possible, with the help of the AMS team. After that, it could be the starting point for additional sub-features like the one you described :) |
Ok guys, quick update. The idea is to modify It should be enough to merge the My concerns:
As always, let me know your thoughts :) |
I think the value of default_includes should be I think the format of how it's specified should be the same as the include param, then you could do: include_from_options = JSONAPI::IncludeDirective(options[:include])
default_includes = JSONAPI::IncludeDirective(serializer.default_includes)
include_directive = default_includes.deep_merge(include_from_options) |
@NullVoxPopuli: thanks, I've been thinking the same and that would be great!
|
@iMacTia you can get the hashes from the include_directive. It's just a fancy wrapper around a hash anyway, and I think it can take its output as input. So, JSONAPI::IncludeDirective.new(options[:include]).to_hash ==
JSONAPI::IncludeDirective.new(
JSONAPI::IncludeDirective.new(options[:include]).to_hash).to_hash (I think) re: 2: that's what unit tests are for :-) |
Good to know, will give it a try now :)! |
@NullVoxPopuli unfortunately this doesn't work well with wildcards. All internal options are also lost after calling Looks like we'll need some sort of ad-hoc implementation. Does it make sense to have it in the same PR? |
? |
@iMacTia @tommiller1 @NullVoxPopuli I wrote some comments in #1843 (comment) that I think relate to this discussion. but I think the comments beginning with #1333 (comment) deserve a new issue as the original issue is really invalid, and in any case, it's getting hard to summarize the current state of discussion. I think the summary would be,
|
@bf4 got it, I agree. Let us fix this to_hash thing and then I'll open a new Issue :) def associations(include_directive = ActiveModelSerializers.default_include_directive)
return unless object
# I simply added this line
include_directive = JSONAPI::IncludeDirective.new(include_directive.to_hash)
Enumerator.new do |y|
self.class._reflections.each do |reflection|
next if reflection.excluded?(self)
key = reflection.options.fetch(:key, reflection.name)
next unless include_directive.key?(key)
y.yield reflection.build_association(self, instance_options)
end
end
end And the result is:
This is because values in |
ah ok. Maybe we need to implement a merge method in the JSONAPI gem. It's owned by one of our maintainers, @beauby :-) |
nested pool requests 😄 ! |
ok, let's for jsonapi as well! |
Related, test written by Rich 47d7848^...bf4:richmolj-master |
…ement rails-api#1333 Added test to cover new feature
I am migrating from 0.9.3 to 0.10.0-rc3 to take advantage of json-api. Based on the current docs, it seems if I want the association's data as part of the response, I will have to specify it as part of 'include' option when calling render in the controller.
Is there a way to specify this in the serializer instead of the controller, so that I can specify it once and everytime I render that serializer, those associations are included in the json-api by default (instead of having to specify it every time I render that object)? That seemed to be the default behavior in the 0.9.x
TLDR: Instead of
something like this:
Maybe it is already there and I missed it. Either way, I would love some clarity.
Thanks!
The text was updated successfully, but these errors were encountered: