我有一个id为| patient_id | client_id | active的表。记录是patient_id唯一的,client_id意味着每个客户每个患者应该只有一个登记。通常我会把它作为主键,但在rails中我将id作为我的主键。
执行此操作的最佳方法是什么?验证
答案 0 :(得分:8)
听起来你有一个模特关系:
class Client < ActiveRecord::Base
has_many :patients, :through => :enrollments
has_many :enrollments
end
class ClientPatient < ActiveRecord::Base
belongs_to :client
belongs_to :patient
end
class Patient < ActiveRecord::Base
has_many :clients, :through => :enrollments
has_many :enrollments
end
要强制执行约束,我会在ActiveRecord中执行此操作,以便在尝试保存打破约束的记录时获得正确的反馈。我只想修改你的ClientPatient模型:
class Enrollment < ActiveRecord::Base
belongs_to :client
belongs_to :patient
validates_uniqueness_of :patient_id, :scope => :client_id
end
要小心,因为虽然这对于小规模应用程序来说非常好,但它仍然容易出现如下所述的竞争条件:http://apidock.com/rails/v3.0.5/ActiveRecord/Validations/ClassMethods/validates_uniqueness_of在“并发和完整性”下
正如他们在那里描述的那样,您还应该为数据库中的表添加唯一索引。这将带来两个直接的好处:
在迁移文件中添加以下内容:
add_index :enrollments, [:patient_id, :client_id], :unique => true
希望这有用:)
编辑(修复了一些命名问题和一些明显的错误):
然后很容易找到您正在寻找的数据:
Client.find_by_name("Bob Smith").patients
Patient.find_by_name("Henry Person").clients
答案 1 :(得分:1)
验证会起作用(Back them up with a unique index!),但是无法在vanilla Rails中获得真正的复合主键。如果你想要一个真正的复合主键,你需要一个gem / plugin - composite_primary_keys就是我找到的那个,但我确信还有其他的。
希望这有帮助!
答案 2 :(得分:0)
在两列中为表添加UNIQUE约束。这是MySQL http://dev.mysql.com/doc/refman/5.0/en/constraint-primary-key.html
的参考