Travis Pessetto
Travis Pessetto

Reputation: 3298

Validation association not working

I have two models: Location and User. Location has_many :users and User belongs_to :location. Now I have a form that uses something similar to:

 <%= form_for @user do |f| %>
 ...
   <%= f.select(:location,:location_id,Location.all.collect{|location| location.name}) %>
 ...
 <%end%>

When inspected it appears that it generates the correct form field for it:

 <select id="user_location_id" name="user[location_id]">
    <option value="Clearfield">Clearfield</option>
    <option value="San Diego">San Diego</option>
  </select>

According to Ruby on Rails: question about validates_presence_of validates_presence_of should work on the model name and in my models I have:

User.rb:

  class User < ActiveRecord::Base
       belongs_to :location
       validates_presence_of :location
   ...

Location.rb:

 class Location < ActiveRecord::Base
      has_many :users    
 ...

What am I doing wrong that would make it so that validates_presence_of doesn't see location when I use validates_presence_of :location, but for some reason works when I use location_id?

Upvotes: 0

Views: 80

Answers (2)

Marek Lipka
Marek Lipka

Reputation: 51151

validates_presence_of :location doesn't add error in following situation:

user = User.new(:location => Location.new)
user.valid? # => true

On the other hand, validates_presence_of :location_id doesn't add error if location with given id doesn't exist:

user = User.new(:location_id => 123)
user.valid? #=> true
Location.find_by_id(user.location_id) #=> nil

Upvotes: 1

Travis Pessetto
Travis Pessetto

Reputation: 3298

I got half-way through writing this question when I noticed my mistake, but in case it benefits someone else I've placed it here.

One may notice that the generated HTML that it isn't an integer that is in the value fields of the options. It is the name. Thus the piece of code having the problem is:

<%= f.select(:location,:location_id,Location.all.collect{|location| location.name}) %>

This is easy enough to fix, just add the id like so:

<%= f.select(:location,:location_id,Location.all.collect{|location| [location.name,location.id]}) %>

Once I did that the values became integers and upon submition of the form I know longer got an error stating that I needed to enter a value for location.

Upvotes: 0

Related Questions