1

undefined method 'find_by' for nil:NilClass

Extracted source (around line #38):

def update
  respond_to do |format|
    if @tag.update(tag_params)
      format.html { redirect_to @tag, notice: 'Tag was successfully updated.' }
      format.json { render :show, status: :ok, location: @tag }
    else
      format.html { render :edit }
      format.json { render json: @artefact.errors, status: :unprocessable_entity }
    end
  end
end

I am working on modifying the scaffold generators to automatically process :relations as has_many, and add iterators to the user-side. For some reason, all the generated classes with have_many relationships have this issue.

On create or update, the record is not created (/modified), and instead this error is shown.

For good measure, here are the form params, even though it doesn't matter what I put there:

{
 "utf8"=>"✓",
         "_method"=>"patch",
         "authenticity_token"=>"",
         "tag"=>{"name"=>"Downloadable",
         "normalized_name"=>"downloadable", 
         "tagged"=>[""]},
 "commit"=>"Update Tag",
 "id"=>"1604f0d6-4b8c-4305-8858-f2db53b1947d"
}

Something that relates, but I'm not sure why:

def tag_params
  params.require(:tag).permit( :name, :normalized_name, tagged: [])
end

If I remove the ability to have an array for tagged, it stops the error. Of course, since it's a has_many, an array is what I want.

Edit: The tip from Mukesh had me looking at before_action which does call

def set_tag
  @tag = Tag.find(params[:id])
end

Edit: I came back to this after some time working on other projects, and it still stumps me.

Here's the complete output (Note: the suggestion from Pravesh Khatri didn't change the error):

Started PATCH "/tags/e4c42c16-f547-4cc4-8d50-cbf85650563a" for 127.0.0.1 at 2016-07-16 22:23:55 -0300
Processing by TagsController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"b5EuyanawfG7lSCTt6aC1jAn8k66epnr5//KeeiC7GkhW6n4BWWJKeHW4OB87N2YGPwuJG2ynZwlzhWcvbQepQ==", "tag"=>{"name"=>"Tag2", "tagged"=>[""]}, "commit"=>"Update Tag", "id"=>"e4c42c16-f547-4cc4-8d50-cbf85650563a"}
 Tag 4ms MATCH (n:`Tag`) WHERE (n.uuid = {n_uuid}) RETURN n ORDER BY n.uuid LIMIT {limit_1} | {:n_uuid=>"e4c42c16-f547-4cc4-8d50-cbf85650563a", :limit_1=>1}
 Tag#tagged 3ms MATCH (tag6) WHERE (ID(tag6) = {ID_tag6}) MATCH (tag6)<-[rel1:`CONCEPTUAL_TAG`]-(result_tagged) DELETE rel1 | {:ID_tag6=>6}
Completed 500 Internal Server Error in 35ms



NoMethodError (undefined method `find_by' for nil:NilClass):

app/controllers/tags_controller.rb:37:in `update'
  Rendering /Users/josh/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout
  Rendering /Users/josh/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
  Rendered /Users/josh/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (5.1ms)
  Rendering /Users/josh/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
  Rendered /Users/josh/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.5ms)
  Rendering /Users/josh/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
  Rendered /Users/josh/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (2.7ms)
  Rendered /Users/josh/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/actionpack-5.0.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (90.9ms)

Edit: It bit me in a related project, and I found that it's happening when:

  • The relationship is has_many and a model_class of false
  • The controller permits the parameter as an array, such as :tagged => []
  • The form is submitted that either creates a new node, or updates an existing node while providing that parameter
Community
  • 1
  • 1
joshfindit
  • 611
  • 6
  • 27
  • Check it is blank or not first by use of this blank? – vipin Jun 17 '16 at 03:14
  • 1
    You are trying to update a `nil` object, first you need to find that object in your update method and then update it. Where is your `@tag` defined? – Pravesh Khatri Jun 17 '16 at 05:07
  • @vipin - Not sure what you mean? – joshfindit Jun 17 '16 at 12:05
  • @PraveshKhatri - `@tag` should be an instance using the `id` that's submitted. Before the update, `@tag` is correct, but for some reason it breaks at `if @tag.update(tag_params)` – joshfindit Jun 17 '16 at 12:24
  • please try to print the `@tag` in your method and check it in your rails console. – Pravesh Khatri Jun 17 '16 at 12:34
  • You could have a `before_action`, though I like the practice of simply having a helper method like `def tag` which does the exact same thing and then you can just call that method. That way you only make a DB call when it's needed – Brian Underwood Jul 24 '16 at 15:28
  • @BrianUnderwood - Could you explain a little more what you mean in terms of the logic flow? – joshfindit Jul 24 '16 at 15:36
  • If you have a `show` action, for example you can just call the `tag` helper method (a private method in the controller). The tag method would have `@tag ||= Tag.find(params[:id])`. The `||=` means that on the first call of the method it will do the fetch, but on any subsequent calls the stored variable will be used. You can also use the memoist gem for this: https://github.com/matthewrudy/memoist – Brian Underwood Jul 24 '16 at 15:39

1 Answers1

1

In your controller ... check action which is executing before update (Top on controller) And check your params

{
 "utf8"=>"✓",
         "_method"=>"patch",
         "authenticity_token"=>"",
         "tag"=>{"name"=>"Downloadable",
         "normalized_name"=>"downloadable", 
         "tagged"=>[""]},
 "commit"=>"Update Tag",
 "id"=>"1604f0d6-4b8c-4305-8858-f2db53b1947d"
}

It has or not.. which is required in that action (in find_by)

Mukesh
  • 921
  • 10
  • 23