2009-05-04 10 views
1

私は、ユーザーが他のユーザーを追跡し、そのメッセージのフィードを取得することができ、小さなさえずりスタイルのマイクロブログサービスを構築しています複数のレールにはActiveRecordを使用して参加し

I持って次のモデル:

class Follow < ActiveRecord::Base 
    belongs_to :follower, :class_name => "User" 
    belongs_to :followee, :class_name => "User" 
end 

class User < ActiveRecord::Base 
    has_many :follows, :foreign_key => 'follower_id', 
         :class_name => 'Follow' 
    has_many :followers, :through => :follows 
    has_many :followed, :foreign_key => 'followee_id', 
         :class_name => 'Follow' 
    has_many :followees, :through => :followed 
    has_many :messages 
end 

class Message < ActiveRecord::Base 
    belongs_to :user 
end 

へ現在のユーザーのフィードを取得、私は次のSQLクエリを実行したい:

SELECT * FROM follows JOIN users JOIN messages WHERE follows.follower_id = current_user.id AND follows.followee_id = users.id AND users.id = messages.user_id; 

これを行うのが正しいのActiveRecordの方法は何ですか?

答えて

1

ないあなたが探しているものを確認しますが、ここでは私の提案です:

私はそう、私はそれの目的が表示されていない、あなたはそのフォロークラスの他の目的を持っていることを前提としています。それを行うには

「正しい方法」(つまり、私は完全に主観の方法)は、実際にこのようなものになるだろう:

class User < ActiveRecord::Base 
    has_and_belongs_to_many :followers, :foreign_key => 'followed_id', 
     :class_name => 'User', :association_foreign_key => 'follower_id', 
     :include => [:messages] 
    has_and_belongs_to_many :follows, :foreign_key => 'follower_id', 
     :class_name => 'User', :association_foreign_key => 'followed_id' 
    has_many :messages 
end 

class Message < ActiveRecord::Base 
    belongs_to :user 
end 

は、その後、次の表の作成:

create_table :users_users, :id => false do |t| 
    t.integer :followed_id 
    t.integer :follower_id 
end 

をそして、あなたがしています設定:

followed = User.find :first 
follower = User.find :last 

followed.followers << follower 

followed.followers.first.messages 
followed.followers.first.followers.first.messages # etc... 

しかし、私が作ったものから、すべてのフォロワーからのすべてのメッセージを表示したい同時に。

これはユーザークラスに

has_and_belongs_to_many :followed_messages, :foreign_key => 'follower_id', 
    :class_name => 'Message', :association_foreign_key => 'followed_id' 

を追加することによって達成することが可能でなければなりませんが、私はそのようにはなるだろうか、正しいのか分かりません。または、関連付けの拡張で達成することは可能かもしれませんが、実際には例はありません。

更新 : 変更することにより:CLASS_NAMEを、それがこのように正確ではありませんので、そのことについて考えていなかった、Message.idに関連付けます。

このように、最初の例のようにUserクラスを実行するのは、「いい」オプションだけです。 私が見ることができる唯一の他のオプションは、関連付けの拡張子(例を挙げることはできません)か、またはおそらくファインダステートメントを使用しています。

has_many :followed_messages, :class_name => 'Message', 
    :finder_sql => 'select * from messages where user_id in(select followed_id from users_users where follower_id = #{id})' 

あなたはおそらく仕事にすべてを取得するためにそのSQL文をカスタマイズする必要がありますが、少なくともあなたは絵:)

+0

has_and_belongs_to_manyアソシエーション:followed_messages、:FOREIGN_KEY => 'follower_id':CLASS_NAME => 'メッセージ'、:association_foreign_key => が生成する 'followed_id' あなたは次のように指定したSQLクエリを実行することができますSQL: SELECT * FROM messages INNER JOINの後に続くmessages.id =が続きます。WHERE(follows.follower_id = ) をfollowee_idが、私はそれが messages.user_id = follows.followee_id する必要があることを行うための方法はありますか? – Shalmanese

1

Keijroの配置は、その後、あなたがフォローテーブルを必要とする場合も、より良い仕事とを取得する必要があります

Follow.all(:joins => { :messages, :users }, :conditions => { "follows.follower_id" => current_user.id, "follows.followee_id" => "users.id", "users.id" => "messages.user_id"}) 
関連する問題