1

私のRails 3プロジェクトでは、followモデルを使って自己参照結合を持つユーザモデルを用意しています。この結合表を使用して、フォローしているユーザーに関連するアクティビティを検索します。私はジョインによって生成されたクエリがジョインモデルの:primary_keyオプションを完全に無視していることを除いて、ほとんど全てが正しく設定されています。ここでhas_many:through:joinテーブルのprimary_keyが動作しない

は、関連するモデルに関連するスキーマです:

create_table "users", :force => true do |t| 
    t.string "email",         :default => "", :null => false 
    t.string "first_name" 
    t.string "last_name" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "follows", :force => true do |t| 
    t.integer "user_id" 
    t.integer "followed_user_id" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "activities", :force => true do |t| 
    t.integer "user_id" 
    t.text  "body" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

は、ここのモデルで団体

class User < ActiveRecord::Base 
    has_many :follows 
    has_many :followed_users, :through => :follows 
    has_many :followed_activities, :through => :follows 
    has_many :activities 
end 
class Follow < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :followed_user, :class_name => "User" 
    has_many :followed_activities, :primary_key => :followed_user, :foreign_key => :user_id, :class_name => "Activity" 
end 

だけで結構以下の作業です。しかし

u = User.first 
u.follows # returns corresponding records from the follows table 
u.followed_users # returns all users that u is following 
u.followed_users.first.activities # returns all activity records corresponding to the first person the user is following 
Follow.first.activities # same as the previous 

、以下は空の配列を返します:

ここで
u.followed_activities 

210は、最後の文から生成されたSQLです:主キーとしてfollows'.id」の使用に参加しようとしているので、それが機能していない理由がある

Activity Load (0.2ms) SELECT `activities`.* FROM `activities` INNER JOIN `follows` ON `activities`.user_id = `follows`.id WHERE ((`follows`.user_id = 1)) 

むしろ「フォロー」より。フォローされたユーザー。

これはバグですか、または、ユーザーモデルのどこかで:primary_key宣言を繰り返す必要がありますか?私は、Railsのapiやどこにいてもどこの言葉も見つけられません。

Railsのバージョン:3.0.7

答えて

0

ジャスティンには、「後続アクティビティ」と呼ばれる2つの関連があります。確かに、彼らは別のコンテキスト(異なるモデル)を持っていますが、私はこのような関連ブロック内の方法を試すことをお願いしたいと思います:

has_many :followed_users, :through => :follows do 
    def activities 
    end 
end 
+0

2つのモデルで「後続アクティビティ」を持つのは良い点です。私はhas_manyを取得する方法を見つけることができる唯一の方法だったので、フォローモデルに関連付けを入れました:働くための関連付け(私はソース宣言をここで動作させることができませんでした)。あなたが言及したように、それをアソシエーションブロックで動作させる方法を工夫しようとしています。私は何をブロックの中に入れますか?ファインダー法? – Justin

+0

はい、配列を収集する場合は、ファインダメソッドまたはイテレータ。関連の中にメソッドを持つという本来の考えは、この本[Advanced Rails Recipes](http:// pragprog。com/book/fr_arr/advanced-rails-recipes) – Anatoly

+0

私はその本を持っていたことを忘れてしまった!本の別のトリックを使用して、私は少し考えを解説しました。私はコメントの中でこれを行う方法を理解できないので、あなたの投稿を少し更新しました。 – Justin

1

レール3.1の標準的な部分になりますし、あなたに取り組むための別のツールを与える可能性があるhttp://rubygems.org/gems/nested_has_many_through、「nested_has_many_through」宝石とデイジーチェーン関係にそれが直感的に私を見つけましたここ

問題それはあなたがこのような何かをできるようになる。

class Author < User 
    has_many :posts 
    has_many :categories, :through => :posts, :uniq => true 
    has_many :similar_posts, :through => :categories, :source => :posts 
    has_many :similar_authors, :through => :similar_posts, :source => :author, :uniq => true 
    has_many :posts_of_similar_authors, :through => :similar_authors, :source => :posts, :uniq => true 
    has_many :commenters, :through => :posts, :uniq => true 
end 

class Post < ActiveRecord::Base 
    belongs_to :author 
    belongs_to :category 
    has_many :comments 
    has_many :commenters, :through => :comments, :source => :user, :uniq => true 
end 

これは私のクエリとコレクションを超簡略化されています。あなたの問題に対する答えを見つけていただければ幸いです。

+0

私はメソッドを使用して、私のクエリをデイジーチェーンをしようとする他のオプションを与えられていない場合あなたは(user.followed_users.activities)を記述しますが、構造化した方法は単純なhas_many:throughだけです。唯一の違いは、私がjoinテーブルで非標準のprimary_keyを使用していることです。 – Justin

+0

ニース、ありがとう!私は彼らが3.1にこれを加えたことを知らなかった。 has_many - >:through - >:sourceは、大量のSQL文に頼らずに複雑なクエリを動作させるために必要なものでした。 – poetmountain

関連する問題