So i have the following code:
def new
@all_areas = Area.all
@area = Area.new
end
The reason i am passing in all_areas is it’s required for a drop down box in the form, Using mongoid and an Area can be recursively embedded in another Area.
My form has the following code:
<% if @all_areas %>
<%= f.label :parent_area %>
<%= f.collection_select(:parent_area, @all_areas, :_id, :name, prompt: "Select a Parent...") %>
<% end %>
However when i submit ‘invalid values, i.e blank name, the ‘new’ page does not render the select box to select a parent.
What is going on here? Is this a bug?
My create action is pretty simple, if it fails validation i just do the following:
else
render 'new'
Why is @all_areas not passed to the view the second time? i have actually fixed it by changing the code in my create action to the following:
else
@all_areas = Area.all
render 'new'
But this is quite surprising, unless i am missing something?
It’s not a bug. The reason for the behaviour is that the
createaction is actually quite separate from thenewaction, so the instance variables you assigned innewdon’t get carried over.render 'new'only renders the view called “new”, it doesn’t actually call thenewaction.newhappens when you issue aGETrequest to/areas/new.createhappens when youPOSTto/areas. Because they’re separate requests, the server doesn’t remember any state – in fact, you could callcreatewithout ever callingnew(say if you used curl from the command line).Basically, your approach is correct, you need to set the
@all_areasinstance variable in both actions. You might want to extract it out into a separate private method to avoid the duplication.