在 Rails 中用一个简单的实体两次引用相同的模型?

Posted

技术标签:

【中文标题】在 Rails 中用一个简单的实体两次引用相同的模型?【英文标题】:Referencing the same model twice in Rails with a simple entity? 【发布时间】:2022-01-12 19:23:23 【问题描述】:

我有两次引用地址实体的运输实体,例如:

并且发货模型如下属于地址实体(address_from,address_to)的两次:

class Shipment < ApplicationRecord
  belongs_to :address_from, :class_name => 'Address'
  belongs_to :address_to, :class_name => 'Address'
end

但我不太清楚它在关系模型的另一端会是什么样子

class Address < ApplicationRecord
  has_one :shipment
end

如果是发货和地址之间的关系,则如下所示:

rails g model Address

rails g model Shipment address:references

但我不太清楚在这种情况下如何将它们关联两次

任何建议将不胜感激,谢谢。

【问题讨论】:

【参考方案1】:

您实际上不能在此处使用单个关联,因为 ActiveRecord 不支持外键可能位于两列之一中的关联。每个has_one/has_many 对应反面的一个外键列。

相反,您需要为 Shipment 上的每个外键在 Address 上建立一个关联:

class Shipment < ApplicationRecord
  belongs_to :address_from, 
     class_name: 'Address',
     inverse_of: :outgoing_shipments
  belongs_to :address_to, 
     class_name: 'Address',
     inverse_of: :incoming_shipments
end

class Address < ApplicationRecord
  has_many :outgoing_shipments,
    class_name: 'Shipment',
    foreign_key: :address_from_id,
    inverse_of: :address_from
  has_many :incoming_shipments,
    class_name: 'Shipment',
    foreign_key: :address_to_id,
    inverse_of: :address_to
end

虽然您可以在此处使用has_one,但您应该注意,除非您在shipments.address_from_idshipments.address_to_id 上添加唯一性约束并进行验证,否则没有什么可以阻止地址进行多次发货。不知道为什么你会想要这个。

【讨论】:

如果您需要将其视为一个单一的关联(以获取传入和传出的货物),则可以使用一些变通方法,例如在两个模型之间创建连接表或使用物化视图。 谢谢 max,它对我有用:D

以上是关于在 Rails 中用一个简单的实体两次引用相同的模型?的主要内容,如果未能解决你的问题,请参考以下文章

如何避免在 MongoDB(使用 Mongoid)或 ActiveRecord(使用 MySQL 的 Rails)中插入两次相同的记录?

实体框架两次插入相同的实体[重复]

代码优先实体框架 - 评论评论功能,相同的评论显示两次

在 EntityListener 中使用带有 PersistenceContext 的 EJB 时,JPA 尝试在数据库中插入相同的实体两次

在 Swift 3(核心数据)中引用实体属性

Ruby on Rails Mountable vs. Full Engine