【问题标题】:Allow only one of multiple attributes in an ActiveRecord model to be present at a time一次只允许 ActiveRecord 模型中的多个属性之一出现
【发布时间】:2016-03-13 01:34:44
【问题描述】:

我正在努力做到这一点,以便在任何给定时间只能填充三列中的一列。

这是我想到的一些伪代码:

class Model < ActiveRecord::Base
  validates :column_one, presence: true,
    absence: true if (:column_two.present? || :column_three.present?)
  validates :column_two, presence: true,
    absence: true if (:column_one.present? || :column_three.present?)
  validates :column_three, presence: true,
    absence: true if (:column_one.present? || :column_two.present?)
end

是否可以在模型级别执行此操作,还是我必须在控制器或参数中进行管理?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 rails-activerecord


    【解决方案1】:

    您可以使用带有unless 的过程:

    validates :column_one, presence: true, unless: Proc.new { |r|
      r.column_two.present? || r.column_two.present?
    }
    validates :column_two, presence: true, unless: Proc.new { |r|
      r.column_one.present? || r.column_three.present?
    }
    validates :column_three, presence: true, unless: Proc.new { |r|
      r.column_one.present? || r.column_two.present?
    }
    

    或命名函数的符号:

    validates :column_one, presence: true, unless: :other_columns_present
    
    private
    
    def other_columns_present
      # do checks here
    end
    

    【讨论】:

      【解决方案2】:

      要在单个验证中进行检查而不重复代码,请使用自定义验证方法:

      class Model < ActiveRecord::Base
        validate :there_can_be_only_one
      end
      
      def there_can_be_only_one
        if [column_one, column_two, column_three].count(&:present?) > 1
          column_with_error = column_one.present? ? :column_one : :column_two
          errors.add(column_with_error,
            "can't be present if any other column in [column_one, column_two, column_three] is also present"
        end
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-24
        • 1970-01-01
        • 2017-02-26
        • 2012-04-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多