ruby 在多态关联中使用has_one或belongs_to

31moq8wy  于 2023-02-03  发布在  Ruby
关注(0)|答案(2)|浏览(228)

我有一个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一起工作?

ds97pgxw

ds97pgxw1#

当表示实体之间的关系时,重要的是要以这样一种方式反映它们,即与它们在真实的生活中的对应物具有逻辑相似性。
可以这么说
企业有一个地址/主要地址
而不是说业务属于某个地址。
如果你想强制一个企业只能有一个地址的数据库约束,你可以创建一个唯一索引。因为它是一个多态关系,我假设它也会被其他模型使用。如果你不需要强制所有模型的唯一性,你可以选择一个部分索引,只在addressable_type是Business的地方创建一个唯一索引。

class AddIndexToAddress < ActiveRecord::Migration
  def change
    add_index :addresses, [:addressable_id, :addressable_type], unique: true, where: "addressable_type = 'Business'"
  end
end

这将工作,如果你只需要严格每个企业一个地址。
这个问题并不清楚你是否有一个额外的关系来管理一个企业的多个地址。在这种情况下,你需要选择一个与包含主地址id的企业的belong_to关系。

class Business < ApplicationRecord
    belongs_to :main_address, class_name: 'Address', foreign_key: :address_id, optional: true
    has_many :addresses, class_name: 'Address', as: :addressable
end

您可以根据业务需求添加验证。

efzxgjgh

efzxgjgh2#

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

class AddMainLocationAddressToBuisnesses < ActiveRecord::Migration[7.0]
  def change
    add_reference :buisnesses, :main_location_address, 
      null: true, 
      foreign_key: { to_table: :addresses }
  end
end
belongs_to :main_location_address, class_name: "Address", optional: true

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

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

将只从地址表中获取第一个连接行,虽然你可以随意添加addresses.main_location布尔列,但它不保证每个可寻址地址实际上只有一个主位置地址,除非你写了一个自定义约束。
但是,如果您使用的是多态关联,那么您已经将引用完整性抛到了九霄云外。

相关问题