Rails:ActiveRecord :: AssociationTypeMismatch:期望超类,获得Subclass

时间:2013-02-08 12:29:45

标签: ruby-on-rails inheritance has-many type-mismatch

我正在尝试为我的应用程序创建一个具有以下主要功能的类模型:

  • 继承(类Place充当FarmDepot的超类。我添加了gem multiple_table_inheritance来实现此目的。
  • Place的关系(可以有多个places

我正在使用Rails 3.2.11和Ruby 1.9.3.p194。

这是我想要实现的粗略类模型。

Class model

您可以在Place模型中找到关系定义:

class Place < ActiveRecord::Base
  acts_as_superclass
  attr_accessible :location, :name, :subtype

  has_many :place_connections, foreign_key: :place_a_id, dependent: :destroy
  has_many :places, through: :place_connections, source: :place_b
  has_many :reverse_place_connections, class_name: :PlaceConnection, \
            foreign_key: :place_b_id, dependent: :destroy
end

以下可以看到Farm模型。 Depot模型看起来是一样的。

class Farm < ActiveRecord::Base
  inherits_from :place
end

但是,当我在Rails控制台中检查关系模型时,我会遇到以下情况:

> farm = Place.first
 => #<Farm place_id: 1, created_at: "2013-02-08 12:19:16", \
                        updated_at: "2013-02-08 12:19:16"> 
> depot = Place.last
 => #<Depot place_id: 6, created_at: "2013-02-08 12:19:44", \
                         updated_at: "2013-02-08 12:19:44"> 
> farm.places = [depot]
ActiveRecord::AssociationTypeMismatch: Place(#42600420) expected, \ 
                                   got Depot(#42518820) ...

您能否判断我是否正确配置了关系?我究竟做错了什么?也许我混淆了模型和协会的单数复数名称。


发现问题

我认为我们(我和我的朋友)发现了问题所在:
每当数据库已经包含两个places的关系并且您尝试用完全相同的对替换这对id时,就会引发类型不匹配错误。如果用另一对替换现有对,则不会弹出错误。

失败示例:

在:

 PlaceConnection
-----------------
place_a | place_b
-----------------
    1        6
-----------------

动作:

> farm = Place.first
 => #<Farm place_id: 1, created_at: "2013-02-08 12:19:16", \
                        updated_at: "2013-02-08 12:19:16"> 
> depot = Place.last
 => #<Depot place_id: 6, created_at: "2013-02-08 12:19:44", \
                         updated_at: "2013-02-08 12:19:44"> 
> farm.places = [depot.place]
ActiveRecord::AssociationTypeMismatch: Place(#42600420) expected, \ 
                                   got Depot(#42518820) ...

工作示例:

在:

 PlaceConnection
-----------------
place_a | place_b
-----------------
    3        2
-----------------

动作:

> farm = Place.first
 => #<Farm place_id: 1, created_at: "2013-02-08 12:19:16", \
                        updated_at: "2013-02-08 12:19:16"> 
> depot = Place.last
 => #<Depot place_id: 6, created_at: "2013-02-08 12:19:44", \
                         updated_at: "2013-02-08 12:19:44"> 
> farm.places = [depot.place]
=> [#<Place id: 6, name: "Some depot", location: "Somewhere", subtype: "Depot", \
   created_at: "2013-02-09 12:51:01", updated_at: "2013-02-09 12:51:01">] 

请注意

我们意识到的另一件事是,按照以下方式扩展关系数组是{和1}}。这可能是我们想要使用的。然而,分配问题可能是一个错误?!

1 个答案:

答案 0 :(得分:1)

在最后一行,尝试替换它:

farm.places = [depot]

用这个:

farm.places = [depot.place]

.place方法应该返回Place的超类实例(技术上是PlaceConnection正在引用的内容),而不是Depot的子类实例。