Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

adding errors to model in rails is not working

Ok this is not making sense. I can add an error to the model, but when I call valid? or save! it deletes the error that I added. However, the regular validations will prevent model from being saved. Why isn't errors.add working?

1.9.3p0 :001 > @order = Order.new(email: '[email protected]')
 => #<Order id: nil, name: nil, address: nil, email: "[email protected]", pay_type: nil, created_at: nil, updated_at: nil, paypal_customer_token: nil, paypal_recurring_profile_token: nil, first_name: nil, last_name: nil, account_details: {}, unit_id_for_plan: nil, invoice: nil, purchased_at: nil> 
1.9.3p0 :002 > @order.valid?
 => true 
1.9.3p0 :003 > @order.errors.add :base, 'error'
 => ["error"] 
1.9.3p0 :004 > @order.errors.size
 => 1 
1.9.3p0 :005 > @order.valid?
 => true 
1.9.3p0 :006 > @order.errors.size
 => 0 
1.9.3p0 :007 > @order.errors.add :base, 'error_again'
 => ["error_again"] 
1.9.3p0 :008 > @order.errors.size
 => 1 
1.9.3p0 :009 > @order.save!
   (0.1ms)  BEGIN
  SQL (0.3ms)  INSERT INTO `orders` (`account_details`, `address`, `created_at`, `email`, `first_name`, `invoice`, `last_name`, `name`, `pay_type`, `paypal_customer_token`, `paypal_recurring_profile_token`, `purchased_at`, `unit_id_for_plan`, `updated_at`) VALUES ('--- {}\n', NULL, '2013-05-23 18:17:18', '[email protected]', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2013-05-23 18:17:18')
   (12.6ms)  COMMIT
 => true 
1.9.3p0 :010 > @order.errors.size
 => 0 

The Order model doesn't contain much validation:

  attr_accessible :address, :email, :name, :pay_type, :paypal_customer_token, :paypal_payment_token, :first_name, :last_name, :account_details, :invoice
  has_one :cart
  has_many :line_items, :through => :cart
  has_many :products, :through => :line_items, :source => :sellable, :source_type => 'Product'
  has_many :airtime_plans, :through => :line_items, :source => :sellable, :source_type => 'AirtimePlan'
  has_many :payment_notifications

  serialize :account_details, Hash  

  validates_presence_of :email

The validates_presence_of :email correctly will prevent save from working, but when I use errors.add :base, it doesn't work.

@LeoCorrea answer led me to come up with this solution:

validate :user_validation, :on => :create
attr_accessor :users_invalid

def user_validation
  if users_invalid
    errors[:base] << "You have invalid user records"
  end
end 

#paypal_payment model in which the order is passed into
elsif resp["status"] == "error"
    #@order.errors.add(:base, resp["body"])
    @order.users_invalid = true
end

The problem is the actual error message I want is in resp["body"]. Right now I just added an unhelpful message "You have invalid user records".

like image 206
JohnMerlino Avatar asked May 23 '13 16:05

JohnMerlino


1 Answers

valid? on a AR model clears the errors array, it does not check for whether you have errors in the errors array or not. As for save! it runs validations which have nothing to do with the errors array. If you want to have errors in your model, you need to add validations to it.

If you read the code for valid? this is what you'll see

ActiveRecord::Validations

def valid?(context = nil)
  context ||= (new_record? ? :create : :update)
  output = super(context)
  errors.empty? && output
end

The call of super(context) is just a call to ActiveModel::Validations#valid? which is the one responsible for clearing the errors array before running validations:

ActiveModel::Validations

def valid?(context = nil)
  current_context, self.validation_context = validation_context, context
  errors.clear
  run_validations!
ensure
  self.validation_context = current_context
end

UPDATE

In order to add your custom errors, you have to do it on a validation method which adds it when the validation is checked. Anything before or after will just be cleared when you re-run validations.

Take a look at this resource http://guides.rubyonrails.org/active_record_validations.html#errors

The errors are added on a method that is called with validation.

like image 138
Leo Correa Avatar answered Sep 23 '22 04:09

Leo Correa