Validation and error messages in has_many association in single form with parent

I am having trouble with validation and user-friendly error messages
when I create a new “Spot” and an associated (has_many) “Title”.

I have the following models:

class Spot < ActiveRecord::Base
has_many :titles,
:dependent => :destroy,
:conditions => “active = 1”

validates_length_of :address,
:in => 1…1000,
:too_short => “The Address cannot be blank.”,
:too_long => “The Address needs to be less than %d
characters”
end

class Title < ActiveRecord::Base
belongs_to :spot

validates_length_of :title,
:in => 1…255,
:too_short => “The Title cannot be blank.”,
:too_long => “The Title needs to be less than %d
characters”,
:message => nil
end

Then in my new.html.ebr view I use multiple objects in
error_messages_for to show both validation results, and I use
fields_for to generate the Spot portion the form.

error_messages_for (:object => [@spot.titles[0], @spot])
<% form_for(@spot) do |f| %>

<% fields_for(@spot.titles[0]) do |t_form| %>


Title

<%= t_form.text_field :title %>


<% end %>

Address
<%= f.text_area :address %>

<%= f.submit "Create" %>

<% end %>

Here are the new and create actions in the Spots controller.

def new
@spot = Spot.new
@spot.titles[0] = Title.new

respond_to do |format|
  format.html # new.html.erb
  format.xml  { render :xml => @spot }
end

end

def create
@spot = Spot.new(params[:spot])
@spot.titles[0] = Title.new(params[:title])
#set the new title
@spot.titles[0].active = 1

respond_to do |format|
  if @spot.save
    flash[:notice] = 'Spot was successfully created.'
    format.html { redirect_to(@spot) }
    format.xml  { render :xml => @spot, :status

=> :created, :location => @spot }
else
format.html { render :action => “new” }
format.xml { render :xml => @spot.errors, :status
=> :unprocessable_entity }
end
end
end

Everything works, but I am seeing a couple of strange things that I
don’t really understand.

First, the title is being validated, which is good, but I don’t have
to include a validates_associated call in the Spot model like I would
if this was a has_one relationship. Why is that?

Second, when there is an error in the title field, error_messages_for
(:object => [@spot.titles[0], @spot]) displays two errors, the first
one is what I expect “The Title cannot be blank.” but I also get an
additional error “Titles is invalid.” This error is part of the @spot
object. I would like to be able to remove this message, because it is
a duplicate, and because I don’t know where to change the verbiage to
something more user friendly.

Thanks for any information.
Nick Carlevaris

NickCB wrote:

something more user friendly.
Active Record does automatic internal validation of has_many
associations.
You can turn it off by putting

def validate_associated_records_for_titles() end

after the has_many call. You can then add your own validates_associated
call with your own error message. Call validates_associated with
:message => nil if you want no error message displayed for the parent
object.


We develop, watch us RoR, in numbers too big to ignore.

Worked like a charm.