mgh
mgh

Reputation: 1021

undefined method `[]' for nil:NilClass error in rails

I have 2 conotrollers and 3 models:

Models:

problem.rb

class Problem < ActiveRecord::Base
  has_many :problemtags
  has_many :tags, :through => :problemtags
end

tag.rb

class Tag < ActiveRecord::Base
  validate :name, :presence => true
  has_many :problemtags
  has_many :problems, :through => :problemtags
end

problemtag.rb

class Problemtag < ActiveRecord::Base
  belongs_to :problem
  belongs_to :tag
end

problems_controller.rb

class ProblemsController < ApplicationController
def new
  @all_tags = Tag.all
  @new_problem = @problem.problemtags.build
end
def create
  params[:tags][:id].each do |tag|
    if !tag.empty?
      @problem.problemtags.build(:tag_id => tag)
    end
  end
end
def problem_params
  params.require(:problem).permit(:reporter_id, :status, :date_time, :trace_code)
end

tags_controller.rb

//tags_controller is generate with scaffold

And I have below code in problems view:

new.html.erb

<%= fields_for(@new_problem) do |f| %>
    <div class="field">
      <%= f.label "All Tags" %><br>
      <%= collection_select(:tags, :id, @all_tags, :id, {}, {:multiple => true}) %>
    </div>
<% end %>

when I run the project, the problem's view is show, but when I complete the textfields and select tags and then click on submit button, I get below error:

NoMethodError in ProblemsController#create
undefined method `[]' for nil:NilClass

Extracted source (around line #22):   
  @problem = @reporter.problems.build(problem_params)

  params[:tags][:id].each do |tag|
    if !tag.empty?
      @problem.problemtags.build(:tag_id => tag)
    end

I do not understand the problem. any one can describe the problem to me?

Upvotes: 1

Views: 185

Answers (3)

mgh
mgh

Reputation: 1021

I found 2 problems in my code:

  1. in new.index.html(in problem view), the submit button is in the form_for and I write the field_for outside the form_for and when I click on submit button, the params hash of tags didn't create.

  2. In collection_select, I forgot to add the name parameter of tag.

Correct new.html.erb code:

<%= form_for @problem do |f| %>
    status: <%= f.text_field :status %><br/>
    datetime: <%= f.datetime_select :date_time %><br/>
    trace code: <%= f.text_field :trace_code %><br/>

    <%= fields_for(@new_problem) do |f| %>
        <div class="field">
          <%= f.label "All Tags" %><br>
          <%= collection_select(:tags, :id, @all_tags, :id,:name, {}, {:multiple => true}) %>
        </div>
    <% end %>
    <%= f.submit %>
<% end %>

Thanks for all of the answers.

Upvotes: 0

Richard Peck
Richard Peck

Reputation: 76774

As stated by your answers, your issue is that you're not sending the right data to your controller (and consequently params[:tags] will be blank):

Form

You're firstly missing the form_builder object in your collection_select (so your tags will likely not be sent inside the correct params hash). Although this may be by design, you need to ensure you're passing the data properly:

<%= fields_for(@new_problem) do |f| %>
    <div class="field">
      <%= f.label "All Tags" %><br>
      <%= f.collection_select(:tags, :id, @all_tags, :id, {}, {:multiple => true}) %>
    </div>
<% end %>

Params

Secondly, we cannot see your form or params hash. This is vital, as your form needs to look like this:

<%= form_for @variable do |f| %>
    <%= f.text_field :value_1 %>
    <%= f.text_field :value_2 %>
<% end %>

This creates a params hash like this:

params { "variable" => { "name" => "Acme", "phone" => "12345", "address" => { "postcode" => "12345", "city" => "Carrot City" }}}

This will be the core reason why your controller will return the [] for nil:NilClass error - you'll be referencing params which don't exist. You'll need to call params[:variable][:tags] as an example

If you post back your params hash, it will be a big help

Upvotes: 1

Saggex
Saggex

Reputation: 3500

You could try using validate :tag_id, :presence => true to check for presence of the needed params.

Upvotes: 0

Related Questions