【问题标题】:Using a has_one or belongs_to in a polymorphic association在多态关联中使用 has_one 或 belongs_to
【发布时间】:2023-02-02 22:07:46
【问题描述】:

我有一个 Business 模型和一个多态的 Address 模型。

每个企业都有一个主要地址,但我想就是否让企业 belong_to 多态模型更好或者说每个企业有一个地址更好

  belongs_to :main_location_address, class_name: "Address"

  has_one :main_location_address, class_name: "Address", as: :addressable

我都试过了,但 belongs_to 仍然需要地址的可寻址属性。

另外,这将如何与 Business 模型和控制器中的 accepts_nested_attributes_for 一起工作?

【问题讨论】:

  • 主要地址是可选的还是必需的?多个企业是否可以共享相同的地址记录,并且当一个地址记录发生变化时,它也会对所有其他企业发生变化)?还是真正的 1:1 关系?
  • 这是 1:1 的关系。我将尝试在问题中更好地解释它。

标签: ruby-on-rails ruby


【解决方案1】:

如果您想确保一个企业实际上只能有一个主要地址,那么您需要使用belongs_to 关联并创建一个外键列。

class AddMainLocationAddressToBuisnesses < ActiveRecord::Migration[7.0]
  def change
    add_reference :buisnesses, :main_location_address, 
      null: false, 
      foreign_key: { to_table: :addresses }
  end
end

由于外键存储在业务表的列中,因此每个业务只能有一个可能的值。

has_one :main_location_address, class_name: "Address", as: :addressable

只会从地址表中获取第一个连接的行。虽然您可以随意添加 addresses.main_location 布尔列,但它不保证每个可寻址实际上只有一个主要位置地址,除非您编写自定义约束。

但是话又说回来,如果您使用的是多态关联,那么您已经将参照完整性抛到了窗外。

【讨论】:

  • 谢谢指点。 has_one :main_location_address 如何保证没有其他记录指向该业务记录,并且如果有多个记录,它仍然只取最上面的记录。要使用 AddMainLocationAddressToBuisnesses 迁移,您不必在 Business 模型中使用 belongs_to 吗?当地址需要可寻址而 Business 可寻址尚未创建时,当创建一个带有地址的新 Business 时,这将如何工作?
  • has_one :main_location_address 永远不会保证每个企业只有一个记录。虽然您可以天真地将 has_one :main_location_address, -&gt;{ where(main_location_address: true) } 范围添加到地址模型中的关联和唯一性验证,但它实际上并不能保证没有重复项。
  • 这只能通过向特定于数据库的数据库表添加约束来真正保证。
  • “当地址需要可寻址且尚未创建业务可寻址时,当使用地址创建新业务时,这将如何工作?”这就是这里的泡菜。您需要插入公司和地址,然后更新公司。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-13
  • 1970-01-01
  • 1970-01-01
  • 2012-12-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多