首页 > 解决方案 > 如果具有相同属性的旧对象关联到同一个当前对象的关联表,则不创建对象

问题描述

我有 has_many: : 通过与 Foo、FooBar 和 Bar 表的关联。这是他们的实现:

Class Foo < ApplicationRecord
  has_many :foo_bars, dependent: :destroy
  has_many :bars, through: :foo_bars
end

Class FooBar < ApplicationRecord
  belongs_to :foo
  belongs_to :bar
end

Class Bar < ApplicationRecord
  has_many :foo_bars, dependent: :destroy
  has_many :foos, through: :foo_bars
end

例子:

bar = Bar.create(name: "bar")
bar.foos << Foo.create(name: "foo")
foo.bars has bar object with name "bar"
bar.foos has foo object with name "foo"

FooBar.first object has foo_id: 1, bar_id: 1

让我们创建一个新的 Bar 对象

bar2 = Bar.create(name: "bar2")

现在我们有两个 bar 对象

我想要做的是,如果 foo.name = "foo" 并且它与名为 "bar" 的 bar 关联,我不想创建一个新的 foo 对象,因为 bar 已经具有 "foo" 的 foo。但是我想创建 foo 对象,如果 foo.name = "foo" 并且它与 bar2 对象相关联,因为 bar2.foos 没有名为 "foo" 的 foo

标签: ruby-on-railsrubyvalidation

解决方案


我不确定你到底想要什么关联,因为所有这些 foobar 都很难解析。但听起来您想根据范围验证唯一性,这可以通过将以下行添加到您想要唯一的模型来完成

validates_uniqueness_of :name, scope: :parent_id

要使用 :scope 选项创建数据库约束以防止可能违反唯一性验证,您必须在数据库中的两个列上创建唯一索引。根据您使用的数据库,您需要查看MySQL 手册以获取有关多列索引的更多详细信息,或者查看PostgreSQL 手册以获取引用一组列的唯一约束示例(也来自 rails guide on validate唯一性)。


推荐阅读