jsonapi-utils icon indicating copy to clipboard operation
jsonapi-utils copied to clipboard

resource_params => NoMethodError: undefined method `keys' for nil:NilClass

Open seanabrahams opened this issue 6 years ago • 2 comments

rails (4.2.8)
jsonapi-utils (0.4.9)
jsonapi-resources (~> 0.8.0)

I have a nested resource where the index action has a code path that executes resource_params which ends up producing:

NoMethodError: undefined method `keys` for nil:NilClass

Due to:

operation = @request.operations.find { |e| e.options[:data].keys & keys == keys }

https://github.com/tiagopog/jsonapi-utils/blob/v0.4.9/lib/jsonapi/utils/request.rb#L77

@request.operations contains:

[#<JSONAPI::Operation:0x007fea7b3b2640 
@operation_type=:find, 
@resource_klass=Api::V2::ArticleResource, 
@options={
  :context=>{}, 
  :filters=>{}, 
  :include_directives=>nil, 
  :sort_criteria=>nil, 
  :paginator=>#<PagedPaginator:0x007fea7b3b2690 @number=1, @size=20>, :fields=>{}}>]

Which does not include a :data key, hence the resulting exception.

One option is to update the offending piece of code to:

operation = @request.operations.find { |e| e.options.fetch(:data, {}).keys & keys == keys }

I'll look into submitting a PR. In the meantime I've rescued the exception.

seanabrahams avatar Jan 03 '18 01:01 seanabrahams

Making this helper method safe seems like a good idea for me and I will sure work on a refactoring asap.

Anyway, I'm curious on how you came to reach that error. Since :data is not present for the given operation and it probably requires the JSON body to be present (eg. POST, PUT, PATCH request), if an empty/bad formatted body is passed it should be verified and treated before calling the controller action.

tiagopog avatar Jan 06 '18 01:01 tiagopog

It was via a request like GET /profile/:profile_id/articles where it was looking for a profile_id in params[:profile_id] OR resource_params[:profile_id].

The question then is, why look in resource_params[:profile_id] if it's a GET request? The answer is that I'm trying to keep the code DRY and avoid a conditional like if request.get?.

Ultimately, calling resource_params, even on a GET request, should not throw an exception (in my opinion).

seanabrahams avatar Jan 08 '18 22:01 seanabrahams