Topic: One Form Two Model Create, Show all validations

I am having a problem with showing all the validations.. 

Class User:
  belongs_to :contact

Class Contact:
  has_one :user


[code=Create Method]
  def create
    @user = User.new(params[:user])
    @contact = Contact.new(params[:contact])
    if @user.valid? && @contact.valid?
      @contact.save!
      @user.contact = @contact
      @user.save!
      flash[:notice] = 'User was successfully created.'
      redirect_to :action => 'list'
    else
      render :action => 'new'
    end
  end
[/code]

My problem is only the first group of validations is showing up.  If I leave a field on the contact object that blank and it fails validation, I get nothing shown to the screen.  No errors are produced, the model just wont save.

How do I get all validations to appear as one group of validations for both models?

Re: One Form Two Model Create, Show all validations

I figured out one part. 

If I change the method to this:

[code=new create method]
  def create
    @user = User.new(params[:user])
    @contact = Contact.new(params[:contact])
    @user.valid?
    @contact.valid?
    if @user.valid? && @contact.valid?
      @contact.save!
      @user.contact = @contact
      @user.save!
      flash[:notice] = 'User was successfully created.'
      redirect_to :action => 'list'
    else
      render :action => 'new'
    end
  end

[/code]

and I add a new section to the view
[code=new view]
<%= error_messages_for 'contact' %>
[/code]

I see the two different sets of errors. 

I guess my real question is, How do I make them one block that contains both sets, and is there an better way to code my create method to accommodate this.

Thanks in advance

Re: One Form Two Model Create, Show all validations

Found the answer in another post

  def create
    @user = User.new(params[:user])
    @contact = Contact.new(params[:contact])
    @user.valid?
    @contact.valid?
    if @user.valid? && @contact.valid?
      @contact.save!
      @user.contact = @contact
      @user.save!
      flash[:notice] = 'User was successfully created.'
      redirect_to :action => 'list'
    else
      @combinedErrors = @user.errors.full_messages + @contact.errors.full_messages
      render :action => 'new'
    end
  end

Now I added a section to the view to check
<% if @combinedErrors != nil && @combinedErrors.length > 0 %>
  <%= render :partial => 'errors' %>
<% end %>

[code=view partial form]
<div class="errorExplanation" id="errorExplanation">
     <h2>
        <%= @combinedErrors.length %>
         error<%= "s" if @combinedErrors.length > 1 %>
         prohibited this user from being saved
     </h2>
     <ul>
     <% @combinedErrors.each do |message| %>
         <li><%= message %></li>
     <% end %>
     </ul>
</div>
[/code]

Does anyone know a better way to write the :create method.  It seems like my way is not very DRY.

Re: One Form Two Model Create, Show all validations

Try this:

  def create
    @user = User.new(params[:user])
    @contact = @user.build_contact(params[:contact])
    if @user.save
      flash[:notice] = 'User was successfully created.'
      redirect_to :action => 'list'
    else
      @combinedErrors = @user.errors.full_messages + @contact.errors.full_messages
      render :action => 'new'
    end
  end

I think this will try to validate & save both models, but I haven't tested it with a has_one association.

Railscasts - Free Ruby on Rails Screencasts