# Custom action on Active Record Validation Failure?

**URL:** <https://www.ruby-forum.com/t/custom-action-on-active-record-validation-failure/96272>\
**Category:** Rails\
**Created:** [June 27, 2006, 9:13pm UTC](https://www.ruby-forum.com/t/custom-action-on-active-record-validation-failure/96272 "2006-06-27T21:13:53Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![blewis](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/c57346/32.png) [@blewis](https://www.ruby-forum.com/u/blewis)\
**Post date:** [June 27, 2006, 9:13pm UTC](https://www.ruby-forum.com/t/custom-action-on-active-record-validation-failure/96272/1 "2006-06-27T21:13:53Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![blewis](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/c57346/32.png) [@blewis](https://www.ruby-forum.com/u/blewis)\
**Post date:** [June 27, 2006, 9:25pm UTC](https://www.ruby-forum.com/t/custom-action-on-active-record-validation-failure/96272/2 "2006-06-27T21:25:47Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![blewis](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/c57346/32.png) [@blewis](https://www.ruby-forum.com/u/blewis)\
**Post date:** [June 27, 2006, 9:43pm UTC](https://www.ruby-forum.com/t/custom-action-on-active-record-validation-failure/96272/3 "2006-06-27T21:43:34Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![blewis](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/c57346/32.png) [@blewis](https://www.ruby-forum.com/u/blewis)\
**Post date:** [July 6, 2006, 8:48pm UTC](https://www.ruby-forum.com/t/custom-action-on-active-record-validation-failure/96272/4 "2006-07-06T20:48:31Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![blewis](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/c57346/32.png) [@blewis](https://www.ruby-forum.com/u/blewis)\
**Post date:** [July 6, 2006, 8:50pm UTC](https://www.ruby-forum.com/t/custom-action-on-active-record-validation-failure/96272/5 "2006-07-06T20:50:43Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![blewis](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/c57346/32.png) [@blewis](https://www.ruby-forum.com/u/blewis)\
**Post date:** [June 27, 2006, 10:51pm UTC](https://www.ruby-forum.com/t/custom-action-on-active-record-validation-failure/96272/6 "2006-06-27T22:51:05Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![blewis](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/c57346/32.png) [@blewis](https://www.ruby-forum.com/u/blewis)\
**Post date:** [July 6, 2006, 8:52pm UTC](https://www.ruby-forum.com/t/custom-action-on-active-record-validation-failure/96272/7 "2006-07-06T20:52:11Z")

</div>

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
