目前正在使用几个相互关联的模型。协会运作良好,但是我试图限制可以属于护理团队模型的用户数量,因此我尝试了下面的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
答案 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。