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? -- Posted via http://www.ruby-forum.com/.
2009/9/14 Kendall Buchanan <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>:> > 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?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
Colin Law wrote:> 2009/9/14 Kendall Buchanan <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>: >> 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. > > ColinSure. 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.amountself.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.priceself.errors.add(:amount, "cannot exceed activity price.") end end end end Mucho thankso for the response. -- Posted via http://www.ruby-forum.com/.
2009/9/14 Kendall Buchanan <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>:> > Colin Law wrote: >> 2009/9/14 Kendall Buchanan <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>: >>> 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.saveI 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> 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. > > -- > Posted via http://www.ruby-forum.com/. > > > >
Colin Law wrote:> 2009/9/14 Kendall Buchanan <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>: >>> 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? > > ColinWell, 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. -- Posted via http://www.ruby-forum.com/.
Kendall Buchanan 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 :amountThis 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 -- Posted via http://www.ruby-forum.com/.
Hi -- On Mon, 14 Sep 2009, Kendall Buchanan wrote:> > Colin Law wrote: >> 2009/9/14 Kendall Buchanan <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>: >>> 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: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) Ruby/Rails training, consulting, mentoring, code review Book: The Well-Grounded Rubyist (http://www.manning.com/black2)