Validations and Transactions

Hey I have a rather complex record set with lots of associated models
all being save by 1 form. So I’ve wrapped the whole thing in a
transaction block, but, does anyone know how I can get Active Record
to return my validation errors?

On 6/26/07, cammo [email protected] wrote:

Hey I have a rather complex record set with lots of associated models
all being save by 1 form. So I’ve wrapped the whole thing in a
transaction block, but, does anyone know how I can get Active Record
to return my validation errors?

Hey Cammo,

This may not be straight forward and it depends on how your transaction
is
setup. If you are creating the objects during the transaction, it will
only
process the entities until it fails, potentially leaving some objects
uninstantiated.

AR errors are attached to the AR instance when it is checked for
validation. So save, create, valid? calls will all run through the
validation steps of a model and attach any errors that were found to
that
instance.

ie.

@my_model.valid? #=> will attach the errors to the @my_model instance.

You get these with a number of methods

@my_model.errors
or in a view
error_messages_for ‘my_model’

If you want to get all the objects to return their errors you might use
something like this in your controller. (sorry can’t check syntax here
)

def create

@my_objects = list_of_object_params.map{ |obj_p| MyModel.new( obj_p ) }

MyObject.transaction do
@my_objects.each{ |obj| obj.save! }
end

rescue
#There is an issue in the transaction here.
@my_objects.each{ |obj| obj.valid? } #=> ensure validation is run on
all
objects
render / redirect / whatever
end

then in your view

<% @my_objects.each do |obj| %>
<% @tmp = obj %>
<%= error_messages_for ‘tmp’ %>
<% end %>

This may not work, it’s not very elegant, and I’ve never tried it before
:wink:
But it may give you some clues to move forward.

Cheers
Daniel

Yeah cool. It’s kinda a shortcoming of transactions, I can see why it
works that way, but it seems a little stupid.

Thanks again, I’ll investigate.