Objects in Views

Hi everyone, I have recently experienced a strange behavior (strange from my knowledge) in rails. In my controllers ‘new’ action, I am creating a few instance variables in the following manner : @controllerModel = ControllerModel.new @model1 = Model1.all @model2 = Model2.all in my ‘new’ view, I am using the @controllerModel to create the form for new and I am using the @model1 & @model2 within the form to populate 2 combo boxes in the following manner : f.select :model1_id, @model1.collect { |m1| [m1.name, m1.id] } f.select :model2_id, @model2.collect { |m2| [m2.name, m2.id] } Now everything works fine, the form is generated fine, there are no errors even the form submit works fine when I ensure that all the required fields (ControllerModel validations). But in the event some of my validations fail and in the controller I do a render :action => ‘new’ I am given an error / exception for @model1 & @model2 being nil. I don’t understand the reason for the same, I am looking for an explanation for this. As a work around of course I found that if I add the following to the view it works out fine, but I don’t understand the flow fully, I want to know why the above mentioned error occurs.

work around in ‘new’ view :

if @controllerModel.errors @model1 = Model1.all @model2 = Model2.all end

Thanks & Regards, Dhruva Sagar.

Stephen Leacock - “I detest life-insurance agents: they always argue that I shall some day die, which is not so.”

Hi everyone,

I have recently experienced a strange behavior (strange from my knowledge) in rails.

In my controllers 'new' action, I am creating a few instance variables in the following manner :

@controllerModel = ControllerModel.new @model1 = Model1.all @model2 = Model2.all

in my 'new' view, I am using the @controllerModel to create the form for new and I am using the @model1 & @model2 within the form to populate 2 combo boxes in the following manner :

f.select :model1_id, @model1.collect { |m1| [m1.name, m1.id] }

f.select :model2_id, @model2.collect { |m2| [m2.name, m2.id] }

Now everything works fine, the form is generated fine, there are no errors even the form submit works fine when I ensure that all the required fields (ControllerModel validations).

But in the event some of my validations fail and in the controller I do a render :action => 'new' I am given an error / exception for @model1 & @model2 being nil. I don't understand the reason for the same, I am looking for an explanation for this.

The reason is that the @model1 and @model2 variables are only available for the initial render of new. They are setup by you in the controller, used in the view erb file to generate the html which is sent to the browser, then they are discarded. Therefore when you get validation failures and wish to show the view again you must set up the variables again. One solution is to have a private method of the controller called something like prepare_for_edit_or_new which you call where appropriate (you will likely have the same problem in edit) or, the solution I prefer, is to have Model1 and Model2 methods get_selection_data or similar that return the equivalent of @model1.collect { |m1| [m1.name, m1.id] } and then call this directly from the view, thus eliminating the need for the variables.

Colin

Hi everyone,

I have recently experienced a strange behavior (strange from my knowledge)

in rails.

In my controllers ‘new’ action, I am creating a few instance variables in

the following manner :

@controllerModel = ControllerModel.new

@model1 = Model1.all

@model2 = Model2.all

in my ‘new’ view, I am using the @controllerModel to create the form for new

and I am using the @model1 & @model2 within the form to populate 2 combo

boxes in the following manner :

f.select :model1_id, @model1.collect { |m1| [m1.name, m1.id] }

f.select :model2_id, @model2.collect { |m2| [m2.name, m2.id] }

Now everything works fine, the form is generated fine, there are no errors

even the form submit works fine when I ensure that all the required fields

(ControllerModel validations).

But in the event some of my validations fail and in the controller I do a

render :action => ‘new’ I am given an error / exception for @model1 &

@model2 being nil. I don’t understand the reason for the same, I am looking

for an explanation for this.

The reason is that the @model1 and @model2 variables are only

available for the initial render of new. They are setup by you in the

controller, used in the view erb file to generate the html which is

sent to the browser, then they are discarded. Therefore when you get

validation failures and wish to show the view again you must set up

the variables again. One solution is to have a private method of the

controller called something like prepare_for_edit_or_new which you

call where appropriate (you will likely have the same problem in edit)

or, the solution I prefer, is to have Model1 and Model2 methods

get_selection_data or similar that return the equivalent of

@model1.collect { |m1| [m1.name, m1.id] } and then call this directly

from the view, thus eliminating the need for the variables.

Colin

Hi Colin,

Thank you very much for your input, I understand it now & yes it happens with edit as well. I think helpers is perhaps the best place to put the code for the @model.collect in.

Thanks & Regards, Dhruva Sagar.

Pablo Picasso - “Computers are useless. They can only give you answers.”

You could ask yourself who knows what are the valid options that a user may select? The answer may be the model, depending on your application. If so then put it in a model method. I am not talking about how to display the selection (drop down, radio buttons, check boxes or whatever), that is a decision for the view and it's helpers. Possibly in the future there may be a need to disallow certain selections based on criteria in the db. In this case if a model method provides the selection the change will be in the model. If you have code like f.select :model1_id, Model1.all.collect { |m1| [m1.name, m1.id] } in the view/helper then it becomes messy. f.select :model1_id, Model1.get_selection_data is arguably better.

Colin

That’s interesting, again thank you very much for you help. I too think that your idea is better :slight_smile:

Thanks & Regards, Dhruva Sagar.

Samuel Goldwyn - “I’m willing to admit that I may not always be right, but I am never wrong.”