在多态关联中更改类型标识符

时间:2012-07-17 10:09:41

标签: ruby-on-rails ruby ruby-on-rails-3 activerecord polymorphism

我正试图以一种奇怪的方式使用Rails的多态关联,而我遇到了一个问题。

多态表为Address

class Address < ActiveRecord::Base
  belongs_to :addressable, polymorphic: true
end

我的数据库有唯一性约束,因此无法再添加两次相同的地址关联。

我还有一个需要两个地址的Trip模型。一个是旅行的起源,另一个是它的目的地。

class Trip < ActiveRecord::Base
  has_one :origin, as: :addressable, class_name: 'Address'
  has_one :destination, as: :addressable, class_name: 'Address'
end

问题是,当Rails创建一个与旅行相关联的地址时,它会使用类名(即“Trip”)来填充addressable_type列。这意味着如果我尝试使用起点和目的地进行旅行,则rails会尝试使用相同的addressable_typeaddressable_id添加两行。这显然在唯一性约束下失败了。

我可以删除唯一性约束,但之后我最终会得到重复的记录,这会混淆Rails,因为它不知道哪条记录是起源,哪条记录是目的地。

我真正想要做的是指定用于addressable_type的字符串:

class Trip < ActiveRecord::Base
  has_one :origin, as: :addressable, class_name: 'Address', type: 'Trip Origin'
  has_one :destination, as: :addressable, class_name: 'Address', type: 'Trip Destination'
end

这可能吗?是否有其他解决方案或我是否需要重新考虑我的数据库架构?

1 个答案:

答案 0 :(得分:2)

我原以为address不应该belongs_to旅行,因为一个地址可能是多次旅行的起源和/或目的地。如果您有唯一性约束,则尤其如此。外键应存储在行程中:

class Address < ActiveRecord::Base
  has_many :trips_as_origin, class_name: "Trip", foreign_key: "origin_id"
  has_many :trips_as_destination, class_name: "Trip", foreign_key: "destination_id"
end

class Trip < ActiveRecord::Base
  belongs_to :origin, class_name: "Address"
  belongs_to :destination, class_name "Address"
end

您需要创建一个将origin_iddestination_id添加到Trip的迁移。