0

在我的项目中,我需要User能够“创建/拥有”自己的对象和“跟踪”(或“跟随”)其他用户创建的对象。这是我的方法:

class User < ActiveRecord::Base
  has_many :widgets
  has_many :gadgets
  has_many :nuggets

  has_many :tracks

  has_many :tracked_widgets, :as => :trackable, :trackable_type => "Widget"
  has_many :tracked_gadgets, :as => :trackable, :trackable_type => "Gadget"
  has_many :tracked_nuggets, :as => :trackable, :trackable_type => "Nugget"
end

class Track < ActiveRecord::Base
  belongs_to :trackable, polymorphic: true
  belongs_to :user
end

class Widget < ActiveRecord::Base  # Gadget and Nugget classes are the same
  has_many :tracks, :as => :trackable
end

表的架构tracks

  create_table "tracks", :force => true do |t|
    t.integer  "user_id"
    t.integer  "trackable_id"
    t.string   "trackable_type"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "tracks", ["trackable_id", "user_id"], :name => "index_tracks_on_trackable_id_and_user_id"

使用此实现,我收到以下错误:

Unknown key: trackable_type (ArgumentError)

查看架构,很明显我没有:trackable_type设置为索引,因此错误消息是有道理的。但是,在我看到的演示多态关系的示例中,我从未见过将______able_type字段设置为索引。这让我想知道我是否在这里遗漏了一些基本的东西。我有这些问题:

  1. 我是否以某种方式错误地设置了has_many:as => :trackable关系?
  2. 如果没有,使用string字段作为有什么问题index吗?
  3. 如果答案只是将:trackable_type字段添加为索引,那么事后最好的方法是什么?添加一个新的迁移来创建:trackable_type index?
4

1 回答 1

0

我终于想出了如何使多态关联适用于这种情况。不知道我明白为什么,但在某些多态情况下不使用:as选项。has_many相反,您必须使用标准:through选项,然后使用:sourceand:source_type选项重新建立多态性。

在我上面的示例has_many中,模型中的语句User需要格式化如下:

has_many :tracked_widgets, :through => :tracks, :source => :trackable, :source_type => "Widget"
has_many :tracked_gadgets, :through => :tracks, :source => :trackable, :source_type => "Gadget"
has_many :tracked_nuggets, :through => :tracks, :source => :trackable, :source_type => "Nugget"

希望这可以帮助任何试图解决类似情况的人。

于 2012-07-07T19:33:34.437 回答