" has_two"模型与多态模型的关系?

时间:2014-11-18 16:06:12

标签: ruby-on-rails activerecord polymorphic-associations has-one

我有一个像这样的多态PLACE模型:

class Place < ActiveRecord::Base
  belongs_to :placeable, polymorphic: :true
...

所以,例如,在我的Lodging模型中,我有类似的东西:

class Lodging < ActiveRecord::Base
has_one :place, as: :placeable, dependent: :destroy
...

他们按预期工作。 关键是现在我想创建一个CarRental模型,这个模型有两个位置,on是拾取位置,另一个是下拉位置。

所以我写道:

class Transportation < ActiveRecord::Base
has_one :start_place, as: :placeable, dependent: :destroy
has_one :end_place, as: :placeable, dependent: :destroy

当然,这不起作用。有关如何做到这一点的任何见解?

编辑1:如果我喜欢

class Transportation < ActiveRecord::Base
has_one :start_place, class_name: 'Place', as: :placeable, dependent: :destroy
has_one :end_place, class_name: 'Place', as: :placeable, dependent: :destroy

有效!但为什么?保存开始或结束信息在哪里?

**编辑2:NOPE,它不工作** 它不起作用...... =(

2 个答案:

答案 0 :(得分:1)

我猜,由于未知的类,协会之前会出错。默认情况下,has_one :start_place假设您指的是不存在的类StartPlace。它将该术语单独化(尽可能最好)并将其转换为CamelCase。一旦您明确指出您的意思是Place,就很清楚。

无论如何你应该添加一个新列。让我们尝试单表继承(STI)。在type表格中添加string类型的places列:

rails generate migration AddTypeToPlaces type:string

...确保它完成它所说的内容,然后迁移并创建新模型:

rails generate model StartPlace --no-migration --parent=Place
rails generate model EndPlace   --no-migration --parent=Place

注意:他们没有获得专用的表格,并且继承自Place,而不是ActiveRecord::Base它应该生成两个空类,即很好,他们从Place继承了东西。

...然后将您的关联恢复到之前没有工作的内容:

has_one :start_place, as: :placeable, dependent: :destroy
has_one :end_place,   as: :placeable, dependent: :destroy

...他们现在应该工作,因为StartPlace被定义为

  <{> Place type等于"StartPlace"

...与EndPlace相对应type

我很久以前就已经对此进行了描述for a similar case

答案 1 :(得分:0)

你的模式对我来说没有意义 - 那些地方属于住宿等等。当然有固定数量的地方,然后他们可以有许多不同的东西吗?在您的架构中,相同的位置可能在数据库中很多次似乎是错误的。我不认为多态关联也是去这里的方式。

我会这样建模:

class Place
  has_many :lodgings
  has_many :starting_transportations, :class_name => "Transportation", :as => :start_place
  has_many :ending_transportations, :class_name => "Transportation", :as => :end_place

class Lodging
  belongs_to :place #using lodgings.place_id

class Transportation
  belongs_to :start_place, :class_name => "Place" #via transportations.start_place_id
  belongs_to :end_place, :class_name => "Place" #via transportations.end_place_id
不过,我认为&#34;位置&#34;是一个比#34; Place&#34;更好的名字。对于现实世界中的物理位置。 &#34;将&#34;听起来太模糊了。