【问题标题】:Rails Custom Validation Across multiple attributesRails 跨多个属性的自定义验证
【发布时间】:2017-03-31 20:22:55
【问题描述】:

我有一个带有以下用户模型的 Rails 应用程序:

卡车 用户

一辆卡车属于具有以下关联的用户:

class Unit < ActiveRecord::Base
  belongs_to :primary_crew_member, :foreign_key => :primary_crew_member_id, :class_name => 'User'
  belongs_to :secondary_crew_member, :foreign_key => :secondary_crew_member_id, :class_name => 'User'
end

Truck 模型上,我进行了验证,以确保primary_crew_member_idsecondary_crew_member_id 始终存在,因为Truck 不能没有用户/船员。

我希望能够做到以下几点:

  • 验证主要或次要机组成员(用户)未分配到任何其他卡车
  • 扩展该验证,我需要确定卡车 A 上的 John Doe 是否是主要机组成员,他不能被分配到任何其他卡车上的主要或次要位置。
  • 进一步扩展 John Doe 应该无法在给定卡车上同时占据主要和次要插槽(双排班)

我用谷歌搜索并提出了一个验证主插槽的验证方法,如下所示:

验证:primary_multiple_assignment

  def primary_multiple_assignment
      if Truck.has_primary(primary_crew_member_id)
        errors.add(:base, "User has already been assigned to another truck.")
      end
  end

  def self.has_primary(primary_crew_member_id)
      primary = Truck.where(primary_crew_member_id: primary_crew_member_id).first
      !primary.nil?
  end

这似乎可行,我可以确保没有用户被分配到任何卡车的主要插槽,除了一个。但是,如上所述,我需要能够满足我的验证要求。所以基本上我试图用一种方法验证多个列,但我不确定它是如何工作的。

我已经阅读了 Rails 自定义验证指南,并且几乎被卡住了。您可能需要提供帮助的任何信息将不胜感激。在此期间,我将继续修补和搜索以找到解决方案。

【问题讨论】:

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


    【解决方案1】:

    您可以通过使用两种验证来做到这一点:

    # validate that the primary or secondary crew member (user) is not assigned to 
    # any other truck
    validates :primary_crew_member, uniqueness: true
    validates :secondary_crew_member, uniqueness: true
    
    # validate that the primary crew member can't be secondary crew member on any 
    # truck (including current one)
    validate :primary_not_to_be_secondary
    
    # validate that the secondary crew member can't be primary crew member on any     
    # truck (including current one)
    validate :secondary_not_to_be_primary
    
    def primary_not_to_be_secondary
      if Truck.where(secondary_crew_member_id: primary_crew_member_id).present?
          errors.add(:base, "Primary crew member already assigned as secondary crew member.")
      end
    end
    
    def secondary_not_to_be_primary
      if Truck.where(primary_crew_member_id: secondary_crew_member_id).present?
          errors.add(:base, "Secondary crew member already assigned as primary crew member.")
      end
    end
    

    【讨论】:

    • 感谢您的回答,从那时起我提出了自己的解决方案,它可以处理一些我没有考虑过的不同边缘情况。很快就会发布我的答案。
    猜你喜欢
    • 1970-01-01
    • 2019-07-10
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-03
    • 1970-01-01
    相关资源
    最近更新 更多