简体   繁体   中英

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?

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

您可以尝试使用validate :tag_id, :presence => true来检查所需参数的存在。

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM