向rails中的模型添加错误无效

Joh*_*ino 8 error-handling ruby-on-rails

好吧这没有意义.我可以向模型添加错误,但是当我调用有效时?还是保存!它删除了我添加的错误.但是,常规验证将阻止模型被保存.为什么不是errors.add工作?

1.9.3p0 :001 > @order = Order.new(email: 'some@email.com')
 => #<Order id: nil, name: nil, address: nil, email: "some@email.com", 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', 'some@email.com', 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 
Run Code Online (Sandbox Code Playgroud)

Order模型不包含太多验证:

  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
Run Code Online (Sandbox Code Playgroud)

validates_presence_of:电子邮件正确将阻止保存工作,但当我使用errors.add:base时,它不起作用.

@LeoCorrea的回答让我想出了这个解决方案:

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
Run Code Online (Sandbox Code Playgroud)

问题是我想要的实际错误信息是resp ["body"].现在我刚刚添加了一条无用的消息"你的用户记录无效".

Leo*_*rea 10

valid?在AR模型上清除错误数组,它不会检查错误数组中是否有错误.至于save!它运行的验证与errors数组无关.如果您想在模型中出现错误,则需要为其添加验证.

如果您阅读此代码,valid?您将会看到

的ActiveRecord ::验证

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

调用super(context)只是一个调用,ActiveModel::Validations#valid?负责在运行验证之前清除错误数组:

::加载ActiveModel验证

def valid?(context = nil)
  current_context, self.validation_context = validation_context, context
  errors.clear
  run_validations!
ensure
  self.validation_context = current_context
end
Run Code Online (Sandbox Code Playgroud)

UPDATE

为了添加自定义错误,您必须在验证方法上执行此操作,该方法在检查验证时添加它.重新运行验证后,将清除之前或之后的任何内容.

请查看此资源http://guides.rubyonrails.org/active_record_validations.html#errors

错误将添加到通过验证调用的方法上.