Don P
Don P

Reputation: 63748

Have a form_for with a value that may be nil

Users have favorite foods. I have a form on my user's page which lets users enter their favorite food:

However, if the user does not have a favorite_food, I get the error First argument in form cannot contain nil or be empty and it highlights @user.favorite_food.

How do I resolve this?

Upvotes: 2

Views: 137

Answers (3)

Jonas Meinerz
Jonas Meinerz

Reputation: 622

Both answers already posted are correct, although they are not complete. For it to work for both an @user that has a favourite_food and one that doesn't, your form needs to do something like this:

<%= form_for (@user.favourite_food || @user.build_favourite_food) do |f| %>

This way, if the user has a favourite food, the form will be automatically and properly filled with the attributes. If the user doesn't, then it will create a new one.

Another good practise is to isolate that logic in a FormHelper.

Hope this was helpful.

Upvotes: 0

Neha
Neha

Reputation: 133

I was facing the same issue when using nested attributes - where has_one or has_many relation exists. My example was "hospital" has_one "contact_detail", and the form was failing if there was no ContactDetail object. To resolve this, I had to build a child object before rendering the forms.

Something like -

@hospital = Hospital.new
@hopital.build_contact_detail   # Name of the association is contact_detail

In your case, I think you should do something like:

@user.build_favorite_food  # Favorite food being name of association

Hope it helps !

Upvotes: 1

Richard Peck
Richard Peck

Reputation: 76784

As per the Rails documentation, you need to provide an ActiveRecord Object in the form_for builder. If you don't have any value yet, you need to supply a new ActiveRecord Object, which is typically done by defining Model.new:

#app/controllers/your_controller.rb
def new
    @object = Model.new
end

#app/views/controller/new.html.erb
<%= form_for @object do |f| %>

However, I have just learnt that you can supply a symbol to the form:

#app/views/controller/new.html.erb
<%= form_for :object do |f| %>

I appreciate this answer is rather broad. If you supply some code, I can amend it to fix to align with your requirements

Upvotes: 1

Related Questions