2009-06-14 3 views
0

has_ many_ polymorphs ActiveRecordプラグインを使用して、両面多型関係の簡単な例を扱っています。私は "猫"と "犬"の2つのクラスを持っています。 "猫"と "犬"はお互いに "友情"を持つことができます。猫は犬と友人になることができます(はい、それは起こります!)そしてもちろん他の猫と一緒にもなります。同じことが犬のためになります。ここに私のモデルは以下のとおりです。has_many_polymorphs CRUDパラメータを安心して設定する方法

class Cat < ActiveRecord::Base 
    validates_presence_of :name 
end 

class Dog < ActiveRecord::Base 
    validates_presence_of :name 
end 

class Friendship < ActiveRecord::Base 
    belongs_to :left, :polymorphic => true 
    belongs_to :right, :polymorphic => true 

    acts_as_double_polymorphic_join(
    :lefts => [:cats, :dogs], 
    :rights => [:dogs, :cats] 
) 
end 

私はこの作業を取得する日間しようとしてきたと私は何かを明らかに不足している必要があります。私は新しい友情を作成しようとすると私が手:私は新しい "友情" を作成しようとしています

ActiveRecord::Schema.define(:version => 20090613051350) do 
    create_table "cats", :force => true do |t| 
    t.string "name" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 
    create_table "dogs", :force => true do |t| 
    t.string "name" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 
    create_table "friendships", :force => true do |t| 
    t.integer "left_id" 
    t.string "left_type" 
    t.integer "right_id" 
    t.string "right_type" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 
end 

NameError (wrong constant name cats): 
    (eval):7:in `before_save' 
app/controllers/friendships_controller.rb:45:in `create' 

または

NameError (wrong constant name dogs): 
    (eval):7:in `before_save' 
app/controllers/friendships_controller.rb:45:in `create' 

この

は私のschema.rbですURLからleft_ typeとleft_idを取得し、POSTパラメータからright_ typeとright_ idを取得するルートを使用して、たとえば/ cats/3/relationshipsにPOSTを実行します。ルーティングが正しくfriendships_コントローラの#create方法をトリガし、その結果のparamsは次のようになります。私は、「レフト」と「権利」の間を分離したいこの質問の範囲外である理由から

Parameters: { 
    "authenticity_token"=>"gG1eh2dXTuRPfPJ5eNapeDqJu7UJ5mFC/M5gJK23MB4=", 
    "left_type"=>"cats", 
    "right_type"=>"dogs", 
    "left_id"=>"3", 
    "right_id"=>"1" 
} 

私は友情が誰にポストされたのかを追跡することができるような方法です(したがって、 "左"と "権利")が、おそらく私のモデルはこれを達成する正しい方法ではありませんか? has_ many_ polymorphsプラグインの目的を誤解しましたか?

def create 
    @friendship= Friendship.new(
    :left_type => params[:left_type], 
    :left_id => params[:left_id], 
    :right_type => params[:right_type], 
    :right_id => params[:right_id] 
) 
    respond_to do |format| 
    if @friendship.save 
     format.xml { 
     render :xml => @friendship, 
     :status => :created, 
     :location => @friendship 
     } 
    else 
     format.xml { 
     render :xml => @friendship.errors, 
     :status => :unprocessable_entity 
     } 
    end 
    end 
end 

そして最後に、私のroutes.rbを::私が言ったように

map.resources :friendships 

map.resources :cats do |cat| 
    cat.resources :friendships, :path_prefix => "/:left_type/:left_id" 
end 

map.resources :dogs do |dog| 
    dog.resources :friendships, :path_prefix => "/:left_type/:left_id" 
end 

、私はこれを理解しようとする自分に長い時間を費やしてきた。ここ#createのfriendships_コントローラからのアクションがあります存在しているドキュメントは古いもの、あまり一般的でないもの、またはあまりにも高度なもの、あるいは場合によっては3つすべて同時に存在するものです。このRoRのもので始めるのは簡単ではない、私はあなたに伝えることができます!私はRoRの能力の本当のメリットがあることを知っていますので、私は存続しますが、これらのヘッド選手のうちのいくつかはとても悪いので、私は禿げたパッチを取得し始めています。経験豊富なRuby/Railsの開発者がたくさんいることは知っています。私は誰かが木工から出てきて、ここで私たちにとって単なる人間であることを説明することを望んでいます。事前に

おかげで、

JS

答えて

0

あなたの猫と犬が豚と友人で、誰が友情を始めたのか知りたいのであれば、私の以前の解決策はあまりに単純すぎます。

class Animal < ActiveRecord::Base 
    belongs_to :creatures, :polymorphic => true 
    named_scope :cats, :conditions => {:creature_type => 'Cat'} 
    named_scope :dogs, :conditions => {:creature_type => 'Dog'} 
    named_scope :pigs, :conditions => {:creature_type => 'Pig'} 
end 

class Cat < ActiveRecord::Base 
    has_many :friends, :as => :creatures 
end 

class Dog < ActiveRecord::Base 
    has_many :friends, :as => :creatures 
end 

class Pig < ActiveRecord::Base 
    has_many :friends, :as => :creatures 
end 

することができますので、あなたがhas_many関連付けを追加することができ

cat.friends.pigsなど、これはあなたが望むものではないかもしれないが、それはあなたがcat.friendsとcat.friends.dogsを呼び出すことができるようになりますcat.dogsとcat.pigsを直接呼び出してください。

class Cat < ActiveRecord::Base 
    has_many :friends, :as => :creatures 
    has_many :dogs, :through => :animal 
    has_many :pigs, :through => :animal 
end 

これがあなたが探しているものであるかどうかはわかりませんが、それは簡単な方法だと思っています。

0

私はおそらく猫と犬のモデルを選ぶと、その後has_and_belongs_to_manyアソシエーションの関連付けを使用したいですか?インクルードは、表は、このようになります。参加後

class Cat < ActiveRecord::Base 
    has_and_belongs_to_many :dogs 
end 

class Dog < ActiveRecord::Base 
    has_and_belongs_to_many :cats 
end 

...

create_table "cats_dogs", :id => false, :force => true do |t| 
    t.integer "cat_id" 
    t.integer "dog_id" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
end 

あなたはどの見つけることcat.dogsとdog.catsを呼び出すことができるだろう「友情を。」

+0

Jamesさん、ありがとうございました。しかし、私は2つ以上の基本クラスを持っているとき、それは少しclunkyになることを開始しないだろうか?私は、他の2人に、第3のクラス、「ブタ」を追加することは何でしたか?また、このモデルは、私がどの関係者が関係の創始者であるか(上記の私の例では「左」)、あるいは何かを誤解しているのを見ることを許しませんでしたか? –

関連する問題