sql - 多态关联和外键引用可以引用同一个表。如何制作新对象?

标签 sql ruby-on-rails ruby

我所拥有的一个简化示例是

class Apple < ActiveRecord::Base
  has_many :bananas, as: :bananable, dependent: destroy
  has_many :bananas
end

class Orange < ActiveRecord::Base
  has_many :bananas, as: :bananable, dependent: destroy
end

class Banana < ActiveRecord::Base
  belongs_to :bananable, polymorphic: true
  belongs_to :apple
end

所以 Banana 可能属于 Apple 或 Orange 作为 bananaable,但无论如何都将通过外键关系属于 Apple。这在水果的背景下似乎有点勉强,但实际模型非常复杂,所以我简化了一些事情。基本上,多态关联定义了 Banana 存在于内部的范围,但 Banana 是 Apple 的一部分,无论其范围如何。

我遇到的问题是当我尝试创建一个新香蕉时。例如:

@Apple.bananas.new(valid_params)

这设置了 bananas 表中的 apple_id 外键列,但没有设置多态关联列(bananable_id 和 bananable_type)。我发现设置两者的唯一方法是如上所述创建一个新香蕉,然后在保存之前手动设置多态关联列。

有更好的方法吗?

也许是这样的:

@banana = @Apple.bananas.new(valid_params)
@Apple.bananables << @banana

或橙子

@banana = @Apple.bananas.new(valid_params)
@Orange.bananables << @banana

到目前为止我想到的最好的是

@banana = @Apple.bananas.new(valid_params)
if params.has_key?(:orange_id)
  @banana.bananable = @orange
else
  @banana.bananable = @apple
end
@banana.save

最佳答案

您可以尝试在 Banana 模型中使用 :inverse_of 属性。我知道 Rails 文档说这没有任何效果,但它似乎确实对我以前的代码有所帮助。您可以试试,但我不做任何保证。

belongs_to :bananable, polymorphic: true, inverse_of: :bananas

根据我的笔记,这有助于 Rails 理解关联及其逆关联之间的关系,对我而言,这使其能够正确识别项目类型。

作为另一种选择,请务必检查验证是否不会破坏您的数据库更新。为了测试,我不得不使用保存!以确保抛出异常,并且我可以发现隐藏的问题在哪里打破了我的联想。

关于sql - 多态关联和外键引用可以引用同一个表。如何制作新对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32771473/

相关文章:

ruby-on-rails - 我的 rails ./bin 目录中有什么?

ruby-on-rails - ActiveRecord 不创建表

mysql - 如何在 SQL Where 条件操作符(> 或 <)中检查 1 个表列

ruby-on-rails - 页面缓存,自动过期/清理器的最佳实践

ruby-on-rails - Ruby 布局继承

ruby-on-rails - 测试委托(delegate)给另一个对象的方法

ruby-on-rails - 如何为 after_save 创建的对象返回验证错误?

sql - Redshift ROUND 函数在某些情况下不舍入?

java - 使用 jdbc 将查询插入数据库时​​出错

mysql不等于不工作