我正在嘗試向我的數據庫添加唯一性約束以阻止將重複條目添加到連接表。但是,它似乎並沒有工作。我沒有連接表的模型,所以我沒有添加模型級驗證。數據庫唯一性約束不會停止通過關聯創建重複記錄
這裏是遷移:
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)「在對象被保存之前驗證該屬性的值是唯一的,它不會在數據庫中創建唯一性約束。 「 –