Rails has_many模型验证

时间:2018-11-27 16:45:56

标签: ruby-on-rails validation model

目前正在使用几个相互关联的模型。协会运作良好,但是我试图限制可以属于护理团队模型的用户数量,因此我尝试了下面的validate方法,但似乎没有引发任何错误或任何错误。用户可以继续将自己加入该团队,以限制数量。有任何想法吗?

user.rb

class User < ApplicationRecord
   devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, :confirmable 
   validates_presence_of :phone, :city, :state, :street, :zip, presence: true, on: :create

   belongs_to :care_team, optional: true
end

care-team.rb

class CareTeam < ApplicationRecord
   NUMBER_OF_PERMITTED_USERS = 3 

   belongs_to :user, optional: true 

   has_many :users

   validate :validate_user_limit

   private
      def validate_user_limit(user)
         raise Exception.new if users.count > NUMBER_OF_PERMITTED_USERS
      end 
end

2 个答案:

答案 0 :(得分:3)

正如documentation所说,方法collection<<(object, …)

  

通过将一个或多个对象的外键设置为集合的主键,将其添加到集合中。请注意,除非父对象是新记录,否则此操作将立即触发更新SQL,而不用等待父对象的保存或更新调用。这还将运行关联对象的验证和回调。

这意味着当您将用户添加到护理团队时,例如

care_team.users << user

立即添加用户。您无需调用care_team.save即可保存更改。 CareTeam的验证将不会应用。这是因为更改发生在user对象中:其care_team_id属性设置为care_team.id,然后在所有验证通过的情况下保存user

因此,您可以通过以下方式在CareTeam中更改验证来应用限制:

def validate_user_limit
  if users.count > NUMBER_OF_PERMITTED_USERS
    errors[:base] << "This care team has already enough users"
  end
end

并致电care_team.save 明确以进行验证。但是,它根本无法解决问题:到那时,用户已经添加到护理团队中。验证将失败,但用户仍将保留在护理团队中。

要解决此问题,应将验证移至User模型:

class User < ApplicationRecord
  validate :validate_care_team_user_limit

  private

  def validate_care_team_user_limit
    if care_team_id && User.where(care_team_id: care_team_id).count >= CareTeam::NUMBER_OF_PERMITTED_USERS
      errors.add(:care_team_id, "User cannot be added to that care team")
    end
  end
end

答案 1 :(得分:0)

您不会在验证中引发异常,仅在条件为true时添加错误:

def validate_user_limit #the (user) param does not go here
  self.errors.add(:users, "Too many users") if users.count > NUMBER_OF_PERMITTED_USERS
end

如果要获取无效记录的异常,请使用save!而不是save,它对无效记录返回false。