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

3 views
Skip to first unread message

NickCB

unread,
Jan 20, 2008, 4:21:01 PM1/20/08
to Ruby on Rails: Talk
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| %>
<p>
<b>Title</b><br />
<%= t_form.text_field :title %>
</p>
<% end %>

<p>
<b>Address</b><br />
<%= f.text_area :address %>
</p>

<p>
<%= f.submit "Create" %>
</p>
<% 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

Mark Reginald James

unread,
Jan 21, 2008, 1:23:14 AM1/21/08
to rubyonra...@googlegroups.com
NickCB wrote:

> 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.

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.

Evgeni Belin

unread,
Apr 29, 2008, 3:54:59 PM4/29/08
to rubyonra...@googlegroups.com
Worked like a charm.
--
Posted via http://www.ruby-forum.com/.
Reply all
Reply to author
Forward
0 new messages