Reputation: 1021
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
Reputation: 1021
I found 2 problems in my code:
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.
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
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
Reputation: 3500
You could try using validate :tag_id, :presence => true
to check for presence of the needed params.
Upvotes: 0