Skip to content
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 IncludeDirective#merge method #27

Closed
wants to merge 7 commits into from
Closed

Conversation

iMacTia
Copy link

@iMacTia iMacTia commented Jul 13, 2016

Added IncludeDirective#merge and #merge! methods
Added runtime_dependency to 'activesupport' (needed for Hash#deep_merge)

All covered with new tests 😄

iMacTia added 2 commits July 13, 2016 19:10
Added IncludeDirective#merge and #merge! methods
Added test to cover the new #merge method
Added runtime_dependency to 'activesupport' (needed for Hash#deep_merge)
@iMacTia
Copy link
Author

iMacTia commented Jul 14, 2016

@beauby: I forgot to mention that this PR is needed to implement AMS#1333 😃

@beauby
Copy link
Owner

beauby commented Jul 14, 2016

Hi @iMacTia - thanks for the PR.
The gem was depending on activesupport before, but I removed the dependency as the only thing from AS we were using was deep_merge!, which I rewrote here. Would you mind updating your PR to use that instead?

@iMacTia
Copy link
Author

iMacTia commented Jul 14, 2016

Completely missed it, it makes sense tough.
Changed and pushed again 👍

hash = to_hash.dup
Parser.deep_merge!(hash, other.to_hash)

IncludeDirective.new(hash, options.merge!(other.options))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The semantics of options is not very clear during a merge.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can I make it clearer 😄?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem here is that if one has two IncludeDirectives with conflicting options, it is not clear to the user how this conflict will be resolved. In this case it's the options of the other hash that will have priority.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I see your point. I took this decision thinking about allow_wildcard (which looks to me like the only available option at the moment). But thinking again about it, it definitely doesn't work well.

Currently you only need to specify allow_wildcard if you have wildcards in your include.
If this is not the case for other, than whatever is in self remain. If you need it in your new hash, instead, that will be merged properly in the result.

The only case this is not working as everyone would expect, is when other.options explicitly contains allow_wildcard: false.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly. I think the proper way of handling that would be to have a dedicated method to merge the options.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, can do that.
Any advice on the logic of it? Can I still do options.merge!(other.options) ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok method is ready, just need a strategy for it, or I can leave the current implementation of options.merge!(other.options) so that the options of the other hash that will have priority.

@beauby
Copy link
Owner

beauby commented Jul 14, 2016

A few nitpicking remarks, but looks good!

@iMacTia
Copy link
Author

iMacTia commented Jul 14, 2016

No problem, will try to address all of them 😄

@iMacTia
Copy link
Author

iMacTia commented Jul 19, 2016

Hi @beauby, just touching base to know if there's anything blocking this at the moment 😄
I'm waiting to know what to do with the dedicated method to merge the options, but everything else should be fixed now

@iMacTia
Copy link
Author

iMacTia commented Jul 21, 2016

@beauby I'm sorry for chasing you, this really is critical for me.
The only other solution is to monkey-patch it from ActiveModelSerializer gem, which is definitely something I wouldn't like to do...

@beauby
Copy link
Owner

beauby commented Jul 21, 2016

Sorry, I've been a bit busy. Will review it tonight!

On Thursday, 21 July 2016, Mattia notifications@github.com wrote:

@beauby https://github.com/beauby I'm sorry for chasing you, this
really is critical for me.
The only other solution is to monkey-patch it from ActiveModelSerializer
gem, which is definitely something I wouldn't like to do...


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#27 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/ACHPYm7Z5mkhRxzz72RIFHnggFBLdELMks5qXzN9gaJpZM4JLsmq
.

Lucas Hosseini
lucas.hosseini@gmail.com

@iMacTia
Copy link
Author

iMacTia commented Jul 21, 2016

Thanks @beauby, no worries I understand 😃
If you can have a look tonight it would be great.

def merge!(other)
merge_result = merge(other)
@hash = merge_result.hash
@options = merge_result.options
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After giving a thought about the options merging thing, I believe the most sane thing to do here is to assume that when one merges an IncludeDirective B into an other IncludeDirective A, we keep A's options.

@beauby
Copy link
Owner

beauby commented Jul 21, 2016

Reviewed the code. However, in order to merge this PR into this gem, I think we would need a JSON API use-case, as this gem is aimed towards JSON API. AMS#1333 goes against the spec (which specifies that when a client explicitly requires associations via include, the server should not add non-requested associations), although it could be useful when using the non-standard Json or Attributes adapters.
If there is no such use-case, the work done here is not lost, but it would then make sense to have it as a monkey-patch within AMS (since the feature would be AMS-specific).

iMacTia added 2 commits July 22, 2016 12:11
… discarded, no more options merge

refactoring of #merge and #merge! (safe method defined in terms of the dangerous one)
removed useless #dup call on to_hash result since to_hash already returns a new object
@iMacTia
Copy link
Author

iMacTia commented Jul 22, 2016

@beauby pushed an updated version after going through your review.
Everything made sense to me, I appreciate your inputs.

Regarding the JSON API use case, I understand the situation.
Unfortunately on AMS gem the IncludeDirective is used regardless of the adapter and that's creating some sort of dependency between them.

That said, the only generic use-case I can imagine for the merge method is when you want to define them on your application logic layer and you need to work with inheritance "extending" your superclass include directive.

Hope that makes sense. If it doesn't and you think this is far from being a useful addition to JSONAPI gem, I can always add it as an extension in AMS 😃

@beauby
Copy link
Owner

beauby commented Sep 20, 2016

As there does not seem to be a JSON API specific need for this feature, I'm going to close this PR and suggest taking it up with AMS. Great work nonetheless!

@beauby beauby closed this Sep 20, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants