避免Rails中的多态关联



(抱歉英语不好)

假设我有型号A、B、C。每个型号都有一个地址。

在"SQL反模式:避免数据库编程的陷阱"一书中(第7章-多态关联)有一种方法可以通过使用"公共超级表"(也称为基表或祖先表)来避免这种关联。

从多态性上讲,它将是:

table addresses:
    id: integer
    parent_type:string  # 'A', 'B' or 'C'
    parent_id: integer

我知道你可以使用交集表,但下面的解决方案看起来更完善:

配方建议创建一个只有id字段(代理键或伪键)的超级表(Addressing),而不是将A、B、C与Address进行多态关联。然后,其他表引用Addressing。这样,作者说,"你可以依靠外键来强制执行数据库的数据完整性"。因此,它将是:

table addressing
    id: integer
table addresses
    id: integer
    addressing_id: integer  (foreign_key)
    zip: string
table a
    id: integer
    addressing_id: integer  (foreign_key)
    name: string
table b
    id: integer
    addressing_id: integer  (foreign_key)
    name: string
table c
    id: integer
    addressing_id: integer  (foreign_key)
    name: string

SQL查询如下所示:

SELECT * from a
  JOIN address USING addressing_id
  WHERE a.addressing_id = 1243 

问题是:如何在Rails中对这样的场景进行编码?我尝试了好几种方法都没有成功。

对象A、B和C都有一个地址吗或者有很多地址从你下面的评论来看,似乎每个对象都有一个地址。

如果每个对象只有一个地址,你可以简单地在带有地址ID的a/B/C对象中放入一个外键。让House或Office对象有一个地址:

class House < ActiveRecord::Base
  belongs_to :address
end
class Office < ActiveRecord::Base
  belongs_to :address
end

您的officehouses DB表需要有一个外键address_id。通过这种方式,您可以使用类似house.addressoffice.address的东西访问对象的地址。

如果这些对象可能有许多地址,则解决方案取决于A/B/C对象。如果它们是相关的,你可以使用单表继承——Rails很好地支持这种模式——但如果没有更多的信息,很难说哪种方法是最好的。

相关内容

  • 没有找到相关文章

最新更新