Rails自定义验证跨多个属性

时间:2017-03-31 20:22:56

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

我有一个带有以下用户模型的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不应该同时使用给定卡车上的主要和辅助插槽(双排册)

我已经用Google搜索并提出了验证主插槽的验证,如下所示:

验证: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自定义验证指南,而且几乎被卡住了。您可能需要提供的任何信息都将不胜感激。与此同时,我将继续修补和谷歌搜索找到解决方案。

1 个答案:

答案 0 :(得分:0)

您可以使用两种验证来完成:

# 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