我想知道是否有办法在自定义操作上使用rails验证。
例如,我想做类似的事情:
validates_presence_of :description, :on => :publish, :message => "can't be blank"
我做基本验证创建和保存,但有很多事情我不想预先要求。即,他们应该能够在不验证所有字段的情况下保存准系统记录,但是我在我的控制器和模型中有一个自定义的“发布”操作和状态,在使用时应验证以确保记录为100%
上面的例子没有用,有什么想法吗?
更新:
我的状态机看起来像这样:
include ActiveRecord::Transitions
state_machine do
state :draft
state :active
state :offline
event :publish do
transitions :to => :active, :from => :draft, :on_transition => :do_submit_to_user, :guard => :validates_a_lot?
end
end
我发现我可以添加警卫,但我仍然希望能够使用rails验证而不是在自定义方法上完成所有操作。
答案 0 :(得分:5)
这看起来更像是业务逻辑而不是模型验证。几年前我参与了一个项目,我们不得不发表文章,当时正在执行许多业务规则。
我建议您执行类似Model.publish()的操作,该方法应该强制执行所有业务规则,以便发布项目。
一种选择是运行自定义验证方法,但您可能需要向模型添加一些字段。这是一个例子 - 我假设你的模型被称为文章
Class Article < ActiveRecord::Base
validate :ready_to_publish
def publish
self.published = true
//and anything else you need to do in order to mark an article as published
end
private
def ready_to_publish
if( published? )
//checks that all fields are set
errors.add(:description, "enter a description") if self.description.blank?
end
end
end
在此示例中,客户端代码应调用an_article.publish
,并且在调用article.save
时,它将自动执行其余操作。这种方法的另一个重大好处是,您的模型将始终保持一致,而不是取决于调用的操作。
答案 1 :(得分:1)
如果您的“发布”操作将某种状态字段设置为“已发布”,那么您可以执行以下操作:
validates_presence_of :description, :if => Proc.new { |a| a.state == 'published' }
或者,如果每个州都有自己的方法
validates_presence_of :description, :if => Proc.new { |a| a.published? }