2009-05-04 54 views
1

我建立一個小的Twitter微博式的服務,用戶可以跟隨其他用戶,並得到他們的消息的飼料多個連接在軌使用ActiveRecord

我有以下型號:

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類。 我能看到的唯一的其他選項是關聯擴展(我不能給你一個例子)或者可能使用finder語句。

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消息INNER JOIN跟在ON messages.id =後面。followee_id WHERE(follows.follower_id = ) ,但我需要它是 messages.user_id = follows.followee_id 有沒有辦法做到這一點? – Shalmanese 2009-05-10 09:10:31

1

Keijro的安排會更好地工作,但如果你需要後續表,然後

Follow.all(:joins => { :messages, :users }, :conditions => { "follows.follower_id" => current_user.id, "follows.followee_id" => "users.id", "users.id" => "messages.user_id"})