【问题标题】:Rails 3 Validation, only one field should be present out of two, and other should be nilRails 3 验证,两个字段中只有一个字段,其他字段为零
【发布时间】:2012-12-08 20:54:55
【问题描述】:

在我的模型 package.rb 中

  validates_presence_of :duration, :unless => :expiration_date?
  validates_presence_of :expiration_date, :unless => :duration?

我只想输入其中一项。其他字段必须设置为零。只有其中一个需要有价值。 但我仍然可以创建一个包含这两个字段的包。可能是其他我遗漏了什么或者我需要使用其他方法吗?这不是正确的做法吗?

【问题讨论】:

标签: ruby-on-rails ruby ruby-on-rails-3 activerecord ruby-on-rails-3.2


【解决方案1】:

尝试创建自定义验证。

validate :expiration

def expiration
  unless duration or expiration_date
    errors.add_to_base "Need a way to determine expiration"
  end
end

【讨论】:

  • 没有帮助,我仍然可以用两者创建一个包,我只需要一个,更改后,或输入其中一个,其他需要为零。
  • 这里不能使用ororand 是控制流修饰符,&&|| 是逻辑运算符。
【解决方案2】:

快速而肮脏的解决方案:

require 'active_model'

class Person
  include ActiveModel::Validations

  attr_accessor :aa, :bb

  validate :only_one_present

  def initialize(options = {})
    self.aa = options[:aa]
    self.bb = options[:bb]
  end

  private

  def only_one_present
    if both_present || no_attr_present
      errors.add(:base, 'Invalid!')
    end
  end

  def both_present
    !aa.nil? && !aa.empty? && !bb.nil? && !bb.empty?
  end

  def no_attr_present
    (aa.nil? || aa.empty?) && (bb.nil? || bb.empty?)
  end
end

puts Person.new(aa: 'asad', bb: 'sdsd').valid? # => false
puts Person.new(aa: nil, bb: 'sdsd').valid? # => true
puts Person.new(aa: 'asad', bb: nil).valid? # => true
puts Person.new(aa: nil, bb: nil).valid? # => false

当然,您必须先编写适当的规范,然后您可以为此提取验证器类。

编辑:

如果使用 ActiveSupport,您可以将 nil?empty? 组合更改为 present?blank?

【讨论】:

    猜你喜欢
    • 2022-12-14
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多