Ruby on rails Rails 3:验证默认值和关联模型中是否存在验证错误
我有一个基本的发票设置与模型:发票,项目,行项目Ruby on rails Rails 3:验证默认值和关联模型中是否存在验证错误,ruby-on-rails,ruby,model-associations,Ruby On Rails,Ruby,Model Associations,我有一个基本的发票设置与模型:发票,项目,行项目 # invoice.rb class Invoice < ActiveRecord::Base has_many :line_items, :dependent => :destroy validates_presence_of :status before_save :default_values def default_values self.status = 'sent' unless self.st
# invoice.rb
class Invoice < ActiveRecord::Base
has_many :line_items, :dependent => :destroy
validates_presence_of :status
before_save :default_values
def default_values
self.status = 'sent' unless self.status
end
end
# item.rb
class Item < ActiveRecord::Base
has_many :line_items
validates_presence_of :name, :price
end
# line_item.rb
class LineItem < ActiveRecord::Base
belongs_to :item
belongs_to :invoice
before_save :default_values
validates_presence_of :invoice_id
validates :item_id, :presence => true
end
因此,有两个问题:
validates:invoice\u id,:presence=>true
我不会再收到行项目发票不能为空的错误消息,但为什么?我确实想验证第\u行项目上的发票\u id,所有第\u行项目都应该有一个发票\u id。如何验证第\u行项目上的发票\u id而不出错
状态设置为默认值,为什么我得到的状态不能为空
错误?我可能可以在控制器上设置它,但我认为应该在模型中设置默认值,对吗?如何验证状态的存在,并在模型中为其保留默认值
发生这两个验证错误的原因是,在保存之前(以及在
before\u save
回调之前)调用了验证
我假设您正在使用嵌套的表单同时创建发票及其行项目。如果是这种情况,您不想在行项目上验证:invoice_id,:presence=>true——发票和行项目同时进入,并且发票尚未保存,因此它没有id。如果您将验证保留在中,则需要先创建并保存空发票,然后稍后创建行项目,以便发票id可用。如果您只想确保在任何编辑之后仍然设置了发票id,则可以通过以下方式强制执行此操作:验证:发票id,:presence=>true,:on=>:update
在创建行项目(且发票id尚不可用)时,此操作将跳过验证
由于类似的原因,validates:status,:presence=>true
会遇到问题-通过请求传入的值正在根据验证,而“status”值不存在。保存前的回调在验证后运行。您可以在\u validation
之前的或\u initialization
之后的回调中设置默认值,这些值将在运行验证时出现
查看Rails文档了解更多信息。我将从2开始:
before save仅在save之前执行,也就是说,在对象通过验证并即将保存之后。如果验证失败-它将不会被执行
关于1:
您能举例说明如何创建发票吗?问题1
尝试检查关联的模型是否都有效
问题2
像大多数答案一样,在验证后调用_save
之前说。您正在寻找的魔法是在调用对象的initialize
方法后运行的after\u initialize
class Invoice < ActiveRecord::Base
after_initialize :default_values
validates :status, presence: true
private
def default_values
self.status ||= 'sent'
end
end
class发票
class Invoice < ActiveRecord::Base
after_initialize :default_values
validates :status, presence: true
private
def default_values
self.status ||= 'sent'
end
end