Rails - 一种模型,两种验证规则

时间:2013-01-30 22:16:20

标签: ruby-on-rails ruby validation attributes

在app中,我有3种类型的联系表单 - 在模型中 - 属性:aaa, :bbb, :ccc属于第二个联系表单,之前的属性属于第一个联系表单。

class Message

  include ActiveModel::Validations
  include ActiveModel::Conversion
  extend ActiveModel::Naming

  attr_accessor :name, :email, :body, :aaa, :bbb, :ccc

  validates :name, :email, :body, :aaa, :bbb, :ccc, :presence => true
  validates :email, :format => { :with => %r{.+@.+\..+} }, :allow_blank => true

  def initialize(attributes = {})
    attributes.each do |name, value|
      send("#{name}=", value)
    end
  end

  def persisted?
    false
  end

end

我想做的是:我正在寻找一种方法,如何验证各个联系表格的属性,具体来说:

  • 第一个联系表单包含属性::name, :email, :body,我需要验证
  • 第二个合同表单包含属性::aaa, :bbb, :ccc, :email,我需要验证

怎么做?如何区分哪些属性属于哪种形式并验证它们?

2 个答案:

答案 0 :(得分:0)

如果有3种类型的合同表格,为什么不将它们分成3个单独的类别? 如果对于某些erason你仍然希望将它保留在一个类中,你可以使用'with_options'魔法来实现它:

with_options :if => :is_form_1? do |p|
  p.validates_presence_of :attr1
  p.validates_presence_of :attr2
  p.validates_presence_of :attr3
end

with_options :if => :is_form_2? do |p|
  p.validates_presence_of :attr4
  p.validates_presence_of :attr5
  p.validates_presence_of :attr6
end

def is_form_1?
  #some logic
end

def is_form_2?
  #some logic
end

尽管如此,我不喜欢将它保持在一个班级的想法。

答案 1 :(得分:0)

我建议你在行为而不是实施条款中考虑这个问题。您提到有三种联系表单,但您将每一种表单的基本用途是什么?在设置模型时,不应该考虑表单

话说回来,你可以用the validation_scopes gem达到你想要的效果。使用validation_scopes,您可以定义可以独立处理的验证规则集。在控制器中,您可以检查适用于上下文的任何验证规则集(即用户填写的表单)。

在您的模型中,您可以设置为每个表单命名的验证范围(或更好,以具有语义值的方式为上下文命名,但我对您的应用程序了解不足以了解上下文的含义),像这样:

validation_scope :form_one_errors do |vs|
  validates :name, :body, :presence => true
end

validation_scope :form_two_errors do |vs|
  validates :aaa, :bbb, :ccc, :presence => true
end

由于需要在两种情况下验证电子邮件,您只需将其设置为正常验证(根据问题中的代码)。

然后在控制器中,例如,形成一个,您可以检查范围以查看该上下文是否有任何错误。请注意,您必须分别针对常规验证错误检查验证范围的错误。

if !message.valid?
  # Do something with message.errors
elsif message.has_form_one_errors?
  # Do something with message.form_one_errors
else 
  # All good
end