Custom action on Active Record Validation Failure?

Instead of having it highlight the bad fields when you enter in a record
that fails validation, is there a way to make it do an action? I’m
looking for something like this:

validates_uniqueness_of :user_id,:url => {:controller => “headline”,
:action => “index”}

so that on failing the uniqueness check, it would go to the headline
controller.

I believe that if you put something like the following in your
controller,
it should work:

def update
@foo = params[:id]
@foo.update_attributes(params[:foo]
rescue
redirect_to :controller => ‘headline’, :action => ‘index’
end

Daniel H. wrote:

I believe that if you put something like the following in your
controller,
it should work:

def update
@foo = params[:id]
@foo.update_attributes(params[:foo]
rescue
redirect_to :controller => ‘headline’, :action => ‘index’
end

More like:

def update
@foo = Foo.find(params[:id])
@foo.attributes = params[:foo]
if @foo.save
flash[:notice] = ‘You saved it!’
redirect_to :action => ‘list’
else
flash[:notice] = ‘You borked it!’
redirect_to :controller => ‘bad_validation’, :action => ‘foo’
end
end

if/else is much, much more performant than exception handling. You can
measure this yourself, write a little test program.

Also remember that rescue would “skip” any other code in-between the
raised exception and the rescue code, which may or may not be a bad
thing.

update_attributes and save are equivalent, I’d stick with
update_attributes

def update_attributes(attributes)
self.attributes = attributes
save
end

Daniel H. wrote:

Out of curiosity, why did you decide to use if/else instead of rescue?
And
why’d you use

@foo.attributes = params[:foo]
if @foo.save

instead of

if @foo.update_attributes(params[:foo])

which does the same thing?

Also, forgot to mention in my original email that redirecting the
browser is
the controller’s responsibility, not the model’s, which is why the
validation methods don’t allow you to specify what URL to go to when
validation fails.

The main missing link in your code is
@foo = Foo.find(params[:id])

Ajay wrote:

if/else is much, much more performant than exception handling. You can
measure this yourself, write a little test program.

Also remember that rescue would “skip” any other code in-between the
raised exception and the rescue code, which may or may not be a bad
thing.

update_attributes and save are equivalent, I’d stick with
update_attributes

def update_attributes(attributes)
self.attributes = attributes
save
end

Out of curiosity, why did you decide to use if/else instead of rescue?
And
why’d you use

@foo.attributes = params[:foo]
if @foo.save

instead of

if @foo.update_attributes(params[:foo])

which does the same thing?

Also, forgot to mention in my original email that redirecting the
browser is
the controller’s responsibility, not the model’s, which is why the
validation methods don’t allow you to specify what URL to go to when
validation fails.

Sorry I didn’t look at your code very closely, also update_attributes
doesn’t throw an exception, so in this case you must use if/else

Ajay wrote:

The main missing link in your code is
@foo = Foo.find(params[:id])

Ajay wrote:

if/else is much, much more performant than exception handling. You can
measure this yourself, write a little test program.

Also remember that rescue would “skip” any other code in-between the
raised exception and the rescue code, which may or may not be a bad
thing.

update_attributes and save are equivalent, I’d stick with
update_attributes

def update_attributes(attributes)
self.attributes = attributes
save
end