我正在尝试设置 2 个模型(实体、用户),其中每个用户可以与多个实体合作,每个实体可以有多个用户与其合作。我希望关系是唯一的,即用户不能与同一个实体合作两次,而实体也不能有同一个用户两次。
我正在使用 has_many 通过关系,并且在“通过”类中存储了访问权限等额外信息。
class Entity < ApplicationRecord
has_many :user_entity_roles, dependent: :destroy
accepts_nested_attributes_for :user_entity_roles
has_many :users, through: :user_entity_roles, dependent: :restrict_with_error
end
class User < ApplicationRecord
has_many :user_entity_roles, dependent: :destroy
has_many :entities, through: :user_entity_roles, dependent: :restrict_with_error
end
class UserEntityRole < ApplicationRecord
belongs_to :entity, touch: true
belongs_to :user
end
现在,由于我构建的表单中出现错误,我创建了重复关系。当然,我可以通过不让表单出现错误来尝试防止这种情况,但我想知道是否有办法强制仅使用用户和实体的唯一组合?
是的。
entity_id
在和上添加唯一索引user_id
将在数据库级别强制唯一性:请注意,在您修复重复数据(例如通过删除重复的行)之前,数据库不会允许您添加此索引。
索引将导致数据库拒绝任何重复数据,从而导致数据库驱动程序错误。为了防止该错误并提供更好的用户反馈,您需要进行应用程序级验证:
验证将捕获大多数潜在的重复项,但不能保证其本身的唯一性,因为它容易出现竞争条件。
如果您想在保存实体时触发此验证,您可以使用
validates_associated
: