我正在尝试向我的数据库添加唯一性约束以阻止将重复条目添加到连接表。但是,它似乎并没有工作。我没有连接表的模型,所以我没有添加模型级验证。数据库唯一性约束不会停止通过关联创建重复记录
这里是迁移:
class CreateBreedsAndTags < ActiveRecord::Migration[5.1]
def change
create_table :breeds do |t|
t.string :name, unique: true, present: true
t.timestamps
end
create_table :tags do |t|
t.string :name, unique: true, present: true
t.timestamps
end
create_join_table :breeds, :tags do |t|
t.integer :breed_id
t.integer :tag_id
t.index [:breed_id, :tag_id], unique: true
end
end
end
的品种和型号标签都非常简单,而且他们使用has_and_belongs_to_many
因为我想测试出的关联。我可以添加-> { distinct }
到协会,但我想停止重复创建的第一个地方。
class Breed < ApplicationRecord
# Some validations and stuff here
has_and_belongs_to_many :tags
end
如果我在轨道控制台中创建品种和标签。我可以做这样的事情即使是在连接表数据库级别唯一约束:
b = Breed.create(name: 'b')
t = Tag.create(name: 't')
b << t
b << t
b.save!
b.tags # outputs the same tag multiple times
编辑:
1)值得一提的是,我发现这个stack overflow其中建议overriting在该<<
协会。但是,这并不能解释为什么我的独特约束失败。
2)我也发现这个stack overflow它建议一个数据库级约束,但这不适合我。
EDIT2:
下面是从数据库中的一些表信息:
,我跑了一个\d breeds_tags
Table "public.breeds_tags"
Column | Type | Modifiers
----------+--------+-----------
breed_id | bigint | not null
tag_id | bigint | not null
Indexes:
"index_breeds_tags_on_breed_id" btree (breed_id)
"index_breeds_tags_on_tag_id" btree (tag_id)
你看过数据库中的连接表通过'psql'(即没有所有的ActiveRecord的东西)? –
@ muistooshort我用一些数据库信息更新了我的答案。它看起来像创建了两个索引,但我没有看到一个唯一的约束?有als oa'breed_tags'表!我基本上从这个[堆栈溢出]运行查询(https://stackoverflow.com/questions/2204058/list-columns-with-indexes-in-postgresql) – Dbz
@Dbz:你说得对。 Rails创建了两个索引;它没有创建独特的约束。 [Rails's uniqueness' helper](http://guides.rubyonrails.org/active_record_validations.html#uniqueness)“在对象被保存之前验证该属性的值是唯一的,它不会在数据库中创建唯一性约束。 “ –