A link
有两个components
:componenta_id
和componentb_id
.为此,Link
我在模型文件中有:
belongs_to :componenta, class_name: "Component" belongs_to :componentb, class_name: "Component" validates :componenta_id, presence: true validates :componentb_id, presence: true validates :componenta_id, uniqueness: { scope: :componentb_id } validates :componentb_id, uniqueness: { scope: :componenta_id }
并在迁移文件中:
create_table :links do |t| t.integer :componenta_id, null: false t.integer :componentb_id, null: false ... end add_index :links, :componenta_id add_index :links, :componentb_id add_index :links, [:componenta_id, :componentb_id], unique: true
问题:这一切都有效.现在,无论他们的顺序如何,我都想要它们的组合componanta
和componentb
独特性.因此无论哪个组件是哪个组件(componenta
哪个是componentb
相同的链接;两个相同组件之间的链接).因此,不应允许下面的两个记录,因为它们代表相同的链接,因此不是唯一的:
componenta_id = 1; componentb_id = 2
componenta_id = 2; componentb_id = 1
如何创建此唯一性验证?我有模型验证工作(见下文),但想知道是否以及如何在迁移/数据库级别添加验证...?
模型验证
我使用以下代码进行模型验证:
before_save :order_links validates :componenta_id, uniqueness: { scope: :componentb_id } private def order_links if componenta_id > componentb_id compb = componentb_id compa = componenta_id self.componenta_id = compb self.componentb_id = compa end end
以下测试证实了上述工作:
1. test "combination of two links should be unique" do 2. assert @link1.valid? 3. assert @link2.valid? 4. @link1.componenta_id = 3 #@link2 already has combination 3-4 5. @link1.componentb_id = 4 6. assert_not @link1.valid? 7. @link1.componenta_id = 4 8. @link1.componentb_id = 3 9. assert_raises ActiveRecord::RecordNotUnique do 10. @link1.save 11. end 12.end
迁移/数据库验证:
作为额外的安全级别,还有一种方法可以在数据库级别上对此进行验证吗?否则,仍然可以将以下两个记录写入数据库:componenta_id = 1 ; componentb_id = 2
以及componenta_id = 2 ; componentb_id = 1
.