2009-05-04 2 views
1

나는 사용자가 다른 사용자에 따라 자신의 메시지를 받기를 얻을 수있는 작은 트위터 스타일의 마이크로 블로깅 서비스를 짓고 있어요여러 레일에 액티브를 사용하여 조인

나는이 다음 모델 :

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이 ON 메시지 다음에옵니다 .id = follows.followee_id WHERE (follows.follower_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"})