- Notifications
You must be signed in to change notification settings - Fork 81
New Feature: Added options to "jsonapi_render" to allow rendering of related resource pages #72
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
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.
Awesome catch again, @MPursche! I made a few comments so we can discuss a bit more about this feature before it goes into master.
spec/spec_helper.rb Outdated
| | ||
| patch :update_with_error_on_base, to: 'posts#update_with_error_on_base' | ||
| | ||
| get :get_related_resources, to: 'posts#get_related_resources' |
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.
Since we're dealing with related resources, what about to define the route like this:
TestApp.routes.draw do jsonapi_resources :users do jsonapi_links :profile jsonapi_related_resource :posts # this will draw the route you need on the tests end jsonapi_resources :posts #... endThere 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 tried change the routes this way but it didn't work for me. I don't know what I did wrong.
But yes this would be a better configuration for the tests.
| records = build_collection(object, options) | ||
| results.add_result(JSONAPI::ResourcesOperationResult.new(:ok, records, result_options(object, options))) | ||
| | ||
| if options[:source_resource].present? && options[:relationship_type].present? |
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.
What about to check for this:
if options[:source_resource].present? && (params[:relationship].present? || options[:relationship_type].present?) # ...This way we would not force the use of relationship_type which is easily inferred from the @request object or via params[:relationship].
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.
That's a good idea. I wasn't aware the params object is available within this method.
| end | ||
| else | ||
| record = turn_into_resource(object, options) | ||
| record = turn_into_resource(object, options) |
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 would be great if this feature also applies to a single related 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.
I don't know if this is necessary. In jsonapi-resources the special handling is only used for has_many relationships, has_one relationships are handled and rendered the same as regular show requests, i.e., the links in the response is to the show page of an object and not the relationships link.
This makes sense as only for the has_many relationship an issue with paging would arise.
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.
Hm, got your point, it makes sense.
I was thinking on the "links"->"self" member for a single resource when I made the suggestion above, but it may not be necessary since it seems to be working properly (I'll double check it later).
| | ||
| if options[:source_resource].present? && options[:relationship_type].present? | ||
| results.add_result(JSONAPI::RelatedResourcesOperationResult.new(:ok, | ||
| options[:source_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.
As it already happens on formatters, you could try inferring some stuff from the params found in the @request object rather than making both :source_resource and :relationship_type mandatory in order to achieve such a feature.
I was also thinking on changing a little bit the way the optionals are passed to the helper method to something like this:
# Usage 1: # - Source resource is inferred: @request.source_klass #=> UserResource # - Relationship is inferred: params[:relationship].to_sym || @request.resource_klass._type #=> :posts jsonapi_render json: @posts, options: { source: @user } # Usage 2: # - Source resource is defined via optionals # - Relationship is inferred: params[:relationship].to_sym || @request.resource_klass._type #=> :posts jsonapi_render json: @posts, options: { source: WeirdNamespace::UserResource.new(@user, context) } # Usage 3: # - Source resource is inferred: @request.source_klass #=> UserResource # - Relationship is defined via optionals jsonapi_render json: @posts, options: { source: @user, relationship: :posts } # Usage 4: # - Source resource is defined via optionals # - Relationship is defined via optionals jsonapi_render json: @posts, options: { source: WeirdNamespace::UserResource.new(@user, context), relationship: :posts }| @MPursche, are you willing to go ahead with this PR or should I take over from now on? |
…ender_related_json
| Hello, sorry for the long delay. I totally forgot about this pull request. I merged with the current master branch and added the discussed changes. The jsonapi_render method now supports the following additional parameter: # Usage 1: # - Source resource is inferred: @request.source_klass #=> UserResource # - Relationship is inferred: params[:relationship].to_sym || @request.resource_klass._type #=> :posts jsonapi_render json: @posts, options: { source: @user } # Usage 2: # - Source resource is defined via optionals # - Relationship is inferred: params[:relationship].to_sym || @request.resource_klass._type #=> :posts jsonapi_render json: @posts, options: { source: WeirdNamespace::UserResource.new(@user, context) } # Usage 3: # - Source resource is inferred: @request.source_klass #=> UserResource # - Relationship is defined via optionals jsonapi_render json: @posts, options: { source: @user, relationship: :posts } # Usage 4: # - Source resource is defined via optionals # - Relationship is defined via optionals jsonapi_render json: @posts, options: { source: WeirdNamespace::UserResource.new(@user, context), relationship: :posts }Greetings Marcel |
| Thanks for this awesome feature, @MPursche :-) |
Hello,
in this pull request I implemented a new feature to allow the correct rendering of related resources pages.
I use
jsonapi-utilsto create JSONAPI resources that are not backed by a database model but computed on the fly. For theindexandshowroutes the output ofjsonapi_renderis as expected. But if a customget_related_resourcesroute is implemented the wrong links were added to the document. This caused my client implementation to load the wrong data for the other pages.Example usage:
If the
source_resource:andrelationship_type:options are set the response is rendered as a related resource and the links for pages are adapted accordingly.Page links before the change for related resource requests:
After: