views:

1724

answers:

2

Hi all,

I have two tables: Client(id,name,...)
Purchase(id,item,date,client_id,...)

They have their respective Model, with their validations. What I need is to create a new client with a new purchase, all into the create method of Client controller. Something like this:

def create  
  @client = Client.new(params[:client])

  respond_to do |format|
    if @client.save
      # Add purchase
      @sell = Purchase.new
      @sell.client_id = @client.id
      @sell.date = params[:date]
      # Fill another fields
      if @sell.save

        # Do another stuff...

      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @client.errors, :status => :unprocessable_entity }
      end

      flash[:notice] = 'You have a new client!'
      format.html { redirect_to(:action => :show, :id => @evento.id) }
      format.xml  { render :xml => @client, :status => :created, :location => @client }
    else
      format.html { render :action => "new" }
      format.xml  { render :xml => @evento.client, :status => :unprocessable_entity }
    end
  end
end

In Purchase's model I have:

belongs_to :client
validates_format_of :date, :with => /^20[0-9]{2}[-][0-9]{2}[-][0-9]{2}$/, :message => 'not valid'
validates_presence_of :date

And there is my problem: how can I validate the date input, through validations into the model, from Client controller? And, how can I rollback the new client created when errors?

Yes, I can do the check as the very first instruction in the method, with a regular expression, but I think it's ugly. I feel like might exist a conventional method for doing this validation or even doing all the stuff in another way (i.e. calling create method for Purchase from Client controller).

Can you put me back in the right way?

Thank you in advance.

+2  A: 

Take a look at the following page on working with associations.

Rails provides you with a bunch of handy methods on your objects.

Like the following:

Client.purchases.empty?
Client.purchases.size,
Client.purchases
Client.purchases<<(purchase)
Client.purchases.delete(purchase)
Client.purchases.find(purchases_id)
Client.purchases.find_all(conditions)
Client.purchases.build
Client.purchases.create

When using these methods, you're taking advantage of the validations on each of the models.

Hop into your Rails console and create a new client and try any of the above methods. You'll quickly learn how powerful they are and you'll be on your way in no time.

Edit: Here's a much better guide on Rails associations!

mwilliams
I've read the documents and tried out. It validates on each model, as waited, but can't correct the input: I force the error inserting a bad date, I see the form again, with the appropiated error message, but I correct the date and... the new date doesn't be inserted into the DB. What am doing bad?
ARemesal
Run your app against the debugger and verify your corrected date is getting passed to the controller. Sounds like you're on the right track though.
mwilliams
+1  A: 

Depends a little on the situation, but you can use validates_associated to run the validations on associated objects. Then you can create the user (but don't save), create the purchase (but don't save) and try to save the user. If you've done it right the user will fail to save with a validation error on the associated object.

Cameron Price