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してポリモーフィズムを再確立する必要があります。:source: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 に答える