我想知道有沒有強制執行了對兩個相關模型的唯一性約束的最好方式,它們都沒有主鍵軌道屬性Rails的兩個值唯一性約束不同型號
class Parent > ApplicationRecord
has_many :children
:name
end
class Child > ApplicationRecord
:name
end
我想以強制(parent.name,child.name)對每個父級都是唯一的。例如
(parent1, child1)
和(parent2, child1)
允許(parent1, child1)
和(parent1, child1)
違反
理想情況下,我會在Postgres的強制執行這一點,但是我只觀察到在的多個列中添加唯一性約束的選項同一張桌子。
另外,我寫了一個自定義驗證器的軌道,做我想要的,但這很麻煩。需要更好的解決方案...
爲了完整起見,下面是約束驗證器,它需要將children
函數添加到返回兒童列表的模型中。
class NamePairValidator < ActiveModel::Validator
def validate(record)
record.children.values.each do |model_children|
names = model_children.to_a.collect {|model| model.name}
if (names.select{|name| names.count(name) > 1 }.size > 0)
record.errors[:name] << 'Path leading to this resource has no unique name'
end
end
end
end
(在Parent.rb)
def children
{children: :children}
end
遷移:
class CreateDomains < ActiveRecord::Migration[5.0]
def change
create_table :domains do |t|
t.string :name
t.string :domain_type
t.timestamps
end
end
end
class CreateSubjects < ActiveRecord::Migration[5.0]
def change
create_table :subjects do |t|
t.string :name
t.string :subject_type
t.timestamps
end
end
end
class CreateJoinTableDomainSubject < ActiveRecord::Migration[5.0]
def change
create_join_table :domains, :subjects do |t|
t.index [:domain_id, :subject_id]
t.index [:subject_id, :domain_id]
end
end
end
您可以展示如何爲您的模型編寫遷移文件?因爲您還可以添加索引以確保數據庫級別的完整性,例如https://robots.thoughtbot.com/the-perils-of-uniqueness-validations –
如果您想在數據庫級別執行此操作,則可以更改'parent_id'列和'child_id'到'parent_name'和'child_name'列中,併爲它們添加唯一約束。對於一些ActiveRecord hackery,可以將這些列用作外鍵。我不確定這個解決方案只是一個想法。 – Ptr
Thx!我認爲你有一個數據透視表!這就是爲什麼Nithin的答案不起作用。請看看這個鏈接:http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association。它可能會幫助你的語法和關係 –