Multiple Model Creat idiom question

I have the case where creating a role for a non-existent entity
requires, naturally enough, that the entity be created as well.

class Entity
has_one :client

class Client
belongs_to :entity

I have this code in my entity_clients_controller

def create
@entity = Entity.new(params[:entity])

# need .datebalk! to strip out observer attributes for datebalks

plugin
# see config/initializers/hash_addins.rb

@client = @entity.build_client(params[:client].datebalk!)

respond_to do |format|
  if @entity.save && @client.save

This works, to a point. My problem is that when a validation error is
thrown in the client role the entity is created nonetheless. Thus, when
the validation error is corrected then the error then becomes that the
entity is already on file. So, what is the correct idiom for handling
this in create action? Do I do a trial save on the dependent model
first?

Hi –

On Wed, 9 Apr 2008, James B. wrote:

I have this code in my entity_clients_controller
respond_to do |format|
if @entity.save && @client.save

This works, to a point. My problem is that when a validation error is
thrown in the client role the entity is created nonetheless. Thus, when
the validation error is corrected then the error then becomes that the
entity is already on file. So, what is the correct idiom for handling
this in create action? Do I do a trial save on the dependent model
first?

You can put validates_associated :client in the Entity model. Then
just do @entity.save. They should then either both be saved or neither
be saved.

David


Rails training from David A. Black and Ruby Power and Light:
ADVANCING WITH RAILS April 14-17 New York City
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
See http://www.rubypal.com for details and updates!

David A. Black wrote:

You can put validates_associated :client in the Entity model. Then
just do @entity.save. They should then either both be saved or neither
be saved.

Works like a charm! Thanks.

Or
On 10/04/2008, at 12:27 AM, David A. Black wrote:

entity is already on file. So, what is the correct idiom for
handling
this in create action? Do I do a trial save on the dependent model
first?

You can put validates_associated :client in the Entity model. Then
just do @entity.save. They should then either both be saved or neither
be saved.

David

Or, you could validate them both before you save.

Julian.

Learn Ruby on Rails! Check out the FREE VIDS (for a limited time)
VIDEO #3 out NOW!
http://sensei.zenunit.com/

Hi –

On Thu, 10 Apr 2008, Julian L. wrote:

thrown in the client role the entity is created nonetheless. Thus,
be saved.

David

Or, you could validate them both before you save.

True, but it’s nice to get the model to do the work. Also you’d have a
bit of race condition (for instance, if someone else saved a record
with a unique field that was the same as one of yours) – though I’m
not at all sure that validates_associated would solve that part of it
either.

David


Rails training from David A. Black and Ruby Power and Light:
ADVANCING WITH RAILS April 14-17 New York City
INTRO TO RAILS June 9-12 Berlin
ADVANCING WITH RAILS June 16-19 Berlin
See http://www.rubypal.com for details and updates!

How about:


Client.transaction do
@client.save
@entity.save
end

respond_to do |format|
if @client.new_record?
… failure response …
else
… success response …
end
end

The transaction will roll back @client if it creates successfully but
@entity fails.

On Apr 17, 8:50 am, James B. [email protected]

David A. Black wrote:

True, but it’s nice to get the model to do the work. Also you’d have a
bit of race condition (for instance, if someone else saved a record
with a unique field that was the same as one of yours) – though I’m
not at all sure that validates_associated would solve that part of it
either.

In this particular case, the uniqueness attribute is enforced at the
DBMS level via a unique index on entity_id in clients and on entity_name
in entities. The validates_associated in both models notwithstanding.
Entity_name is normalized to a lowercase sting with all leading,
trailing, and excess whitespace removed.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs