I have a rails form which takes the rails model FlsCenter and orders them alphabetically to be displayed in a drop down. When none of the fields of the form are filled out, and the form is submitted, the page gets a 500 Server Error in which the following Rails error is displayed:
undefined method `map' for nil:NilClass
Where the map function is in the following view code:
= f.select(:fls_center, @fls_centers.map{|p| [p.name, p.id]}, prompt: "Select a Program Center", selected:@school_application.fls_center)
Where @fls_centers is defined in the new method of my SchoolApplicationController here:
@fls_centers = FlsCenter.order('name ASC')
Here are the relevant controller methods from SchoolApplicationsController
def create
@school_application = SchoolApplication.new(school_application_params)
if @school_application.save_with_payment
redirect_to pay_path(id: @school_application.id)
else
@school_application.errors.full_messages.each do |msg|
flash.now[:error] = msg
end
render action: "new"
end
end
And here is my new method:
def new
if application_params
@school_application = SchoolApplication.new(application_params)
else
@school_application = SchoolApplication.new()
end
Rails.logger.debug(@fls_centers)
@fls_centers = FlsCenter.order('name ASC')
end
The only thing I can imagine that is going wrong is that render action: "new" does not execute the variable instantiation inside the new method. I do not know how to amerliorate this situation. Thank you
2 个答案:
答案 0 :(得分:1)
You are executing Rails.logger.debug(@fls_centers) before defining the @fls_centers, So make changes like shown below:
def new
@fls_centers = FlsCenter.order('name ASC')
if application_params
@school_application = SchoolApplication.new(application_params)
else
@school_application = SchoolApplication.new()
end
Rails.logger.debug(@fls_centers)
end
Hope it helps!
答案 1 :(得分:0)
You guessed right. The actual new method does not get executed when you call
render action: "new"
You will have to call the variable instantiations all over again:
def create
@school_application = SchoolApplication.new(school_application_params)
if @school_application.save_with_payment
redirect_to pay_path(id: @school_application.id)
else
@school_application.errors.full_messages.each do |msg|
flash.now[:error] = msg
end
@fls_centers = FlsCenter.order('name ASC')
render action: "new"
end
end
If you have a lot of them it might be better to refactor them in a method and call that method in the new method as well as before the render call.