# Model.valid? = false, the model still saves

**URL:** <https://www.ruby-forum.com/t/model-valid-false-the-model-still-saves/175503>\
**Category:** Rails\
**Created:** [September 14, 2009, 10:39pm UTC](https://www.ruby-forum.com/t/model-valid-false-the-model-still-saves/175503 "2009-09-14T22:39:59Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![mercurykjb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a9adbd/32.png) [@mercurykjb](https://www.ruby-forum.com/u/mercurykjb)\
**Post date:** [September 14, 2009, 10:39pm UTC](https://www.ruby-forum.com/t/model-valid-false-the-model-still-saves/175503/1 "2009-09-14T22:39:59Z")

</div>

I have a model w/ three validations in PaymentApplication:

validate :total\_applications\_cannot\_exceed\_payment\_amount  
validate :cannot\_exceed\_activity\_price  
validates\_numericality\_of :amount

I can confirm that one of them is firing, and that  
payment\_application.valid? is returning false after calling the ‘save’  
method on a new payment\_application. The record, however, is getting  
saved to the database. I’d like it to not save.

Am I missing something simple?

---

<div class="post-metadata">

**Author:** ![mercurykjb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a9adbd/32.png) [@mercurykjb](https://www.ruby-forum.com/u/mercurykjb)\
**Post date:** [September 14, 2009, 10:58pm UTC](https://www.ruby-forum.com/t/model-valid-false-the-model-still-saves/175503/2 "2009-09-14T22:58:00Z")

</div>

2009/9/14 Kendall B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> saved to the database. I’d like it to not save.
> 
> Am I missing something simple?

Are you sure it is getting saved? Are you checking the return from  
save, it should return false if the save fails. If you still think it  
is not functioning correctly post the relevant section of controller  
code here.

Colin

---

<div class="post-metadata">

**Author:** ![mercurykjb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a9adbd/32.png) [@mercurykjb](https://www.ruby-forum.com/u/mercurykjb)\
**Post date:** [September 14, 2009, 11:04pm UTC](https://www.ruby-forum.com/t/model-valid-false-the-model-still-saves/175503/3 "2009-09-14T23:04:36Z")

</div>

Colin L. wrote:

> 2009/9/14 Kendall B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> 
> > saved to the database. I’d like it to not save.
> > 
> > Am I missing something simple?
> 
> Are you sure it is getting saved? Are you checking the return from  
> save, it should return false if the save fails. If you still think it  
> is not functioning correctly post the relevant section of controller  
> code here.
> 
> Colin

Sure.

Yeah, it’s getting saved by an INSERT statement. Here’s the controller  
code:

def create  
@activity = Activity.find(params[:activity\_id])  
@payment\_application =  
@activity.payment\_applications.new(params[:payment\_application])

```
respond_to do |format|
  if @payment_application.save
    format.html { redirect_to(@payment_application) }
    format.js { index }
    format.apply_to_activity { index }
    format.xml { render :xml => @payment_application, :status => 

```

:created, :location =\> @payment\_application }  
else  
format.html { render :action =\> “new” }  
format.js { render :action =\> “new”, :status =\>  
:unprocessable\_entity }  
format.apply\_to\_activity { index }  
format.xml { render :xml =\> @payment\_application.errors,  
:status =\> :unprocessable\_entity }  
end  
end  
end

And the model code:

class PaymentApplication \< ActiveRecord::Base  
belongs\_to :activity  
belongs\_to :payment

after\_create :apply\_full, :if =\> :apply\_full\_payment

attr\_accessor :apply\_full\_payment  
attr\_accessor :amount\_as\_str

acts\_as\_ferret :fields =\> { :payment\_id =\> { :store =\> :yes },  
:check\_num =\> { :store =\> :yes },  
:comments =\> { :store =\> :yes } }

validate :total\_applications\_cannot\_exceed\_payment\_amount  
validate :cannot\_exceed\_activity\_price  
validates\_numericality\_of :amount

def amount=(value)  
unless value.blank?  
write\_attribute(:amount, Accounting.string\_as\_int(value))  
else  
write\_attribute(:amount, nil)  
end  
end

protected

```
def apply_full
  write_attribute(:amount, self.payment.amount)
  write_attribute(:comments, self.payment.comments)
  self.save
end

def total_applications_cannot_exceed_payment_amount
  if self.payment
    if self.payment.payment_applications.sum(:amount) + self.amount 

```

> self.payment.amount  
> self.errors.add(:amount, “of all payment applications cannot  
> exceed total payment amount.”)  
> end  
> end  
> end

```
def cannot_exceed_activity_price
  if self.payment
    if self.payment.payment_applications.sum(:amount) + self.amount 

```

> self.activity.price  
> self.errors.add(:amount, “cannot exceed activity price.”)  
> end  
> end  
> end

end

Mucho thankso for the response.

---

<div class="post-metadata">

**Author:** ![mercurykjb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a9adbd/32.png) [@mercurykjb](https://www.ruby-forum.com/u/mercurykjb)\
**Post date:** [September 14, 2009, 11:21pm UTC](https://www.ruby-forum.com/t/model-valid-false-the-model-still-saves/175503/4 "2009-09-14T23:21:25Z")

</div>

2009/9/14 Kendall B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> > code here.  
> > Â Â @payment\_application =  
> > @activity.payment\_applications.new(params[:payment\_application])
> 
> Â Â respond\_to do |format|  
> Â Â Â if @payment\_application.save

I don’t know if it is a factor but I have never tried putting the save  
inside the respond\_to. The first thing I would do is to take it out to  
see if that is a factor. Unless you know it is not that.

How do you know that valid? is failing at this point?

Colin

---

<div class="post-metadata">

**Author:** ![mercurykjb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a9adbd/32.png) [@mercurykjb](https://www.ruby-forum.com/u/mercurykjb)\
**Post date:** [September 14, 2009, 11:37pm UTC](https://www.ruby-forum.com/t/model-valid-false-the-model-still-saves/175503/5 "2009-09-14T23:37:23Z")

</div>

Kendall B. wrote:

> I have a model w/ three validations in PaymentApplication:
> 
> validate :total\_applications\_cannot\_exceed\_payment\_amount  
> validate :cannot\_exceed\_activity\_price  
> validates\_numericality\_of :amount

This might be a shot in the dark, I’m not completely sure what happens  
when calling validate with the symbol following, but are you sure the  
second call to validate override the first? I think there should be only  
one custom validation method on a model that does all your custom  
validations.

Try removing the second validate and add both symbols to one validate as  
shown in this example:  
class Invoice \< ActiveRecord::Base  
validate :expiration\_date\_cannot\_be\_in\_the\_past,  
:discount\_cannot\_be\_greater\_than\_total\_value

def expiration\_date\_cannot\_be\_in\_the\_past  
errors.add(:expiration\_date, “can’t be in the past”) if  
!expiration\_date.blank? and expiration\_date \< Date.today  
end

def discount\_cannot\_be\_greater\_than\_total\_value  
errors.add(:discount, “can’t be greater than total value”) if  
discount \> total\_value  
end  
end

---

<div class="post-metadata">

**Author:** ![mercurykjb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a9adbd/32.png) [@mercurykjb](https://www.ruby-forum.com/u/mercurykjb)\
**Post date:** [September 14, 2009, 11:25pm UTC](https://www.ruby-forum.com/t/model-valid-false-the-model-still-saves/175503/6 "2009-09-14T23:25:05Z")

</div>

Colin L. wrote:

> 2009/9/14 Kendall B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> 
> > > code here.  
> > > Â Â @payment\_application =  
> > > @activity.payment\_applications.new(params[:payment\_application])
> > 
> > Â Â respond\_to do |format|  
> > Â Â Â if @payment\_application.save
> 
> I don’t know if it is a factor but I have never tried putting the save  
> inside the respond\_to. The first thing I would do is to take it out to  
> see if that is a factor. Unless you know it is not that.
> 
> How do you know that valid? is failing at this point?
> 
> Colin

Well, that’s pretty standard for REST controllers. Alls I do is output  
@payment\_application.valid? and I get ‘false’ while the record is still  
getting saved.

---

<div class="post-metadata">

**Author:** ![mercurykjb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a9adbd/32.png) [@mercurykjb](https://www.ruby-forum.com/u/mercurykjb)\
**Post date:** [September 14, 2009, 11:41pm UTC](https://www.ruby-forum.com/t/model-valid-false-the-model-still-saves/175503/7 "2009-09-14T23:41:55Z")

</div>

Hi –

On Mon, 14 Sep 2009, Kendall B. wrote:

> > code here.
> > 
> > Colin
> 
> Sure.
> 
> Yeah, it’s getting saved by an INSERT statement. Here’s the controller  
> code:

Nothing definite springs to mind, but a couple of questions:

At the moment you’re getting the “false” result, what do the errors  
look like?

Your validations have a big “if” in them (if self.payment). What’s the  
status of that when the record is being saved?

You have an after\_create hook. Is it possible that that hook is doing  
something that’s making the record invalid after it’s already been  
saved?

David

–  
David A. Black, Director  
Ruby Power and Light, LLC ([http://www.rubypal.com](http://www.rubypal.com))  
Ruby/Rails training, consulting, mentoring, code review  
Book: The Well-Grounded Rubyist ([The Well-Grounded Rubyist](http://www.manning.com/black2))

---

<div class="post-metadata">

**Author:** ![mercurykjb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a9adbd/32.png) [@mercurykjb](https://www.ruby-forum.com/u/mercurykjb)\
**Post date:** [September 14, 2009, 11:52pm UTC](https://www.ruby-forum.com/t/model-valid-false-the-model-still-saves/175503/8 "2009-09-14T23:52:48Z")

</div>

Fantastic! Thanks so much. I changed after\_create to a  
before\_validation, and it worked.
