문제

나는 사용자가 다른 사용자를 팔로우하고 메시지 피드를받을 수있는 작은 트위터 스타일 마이크로 블로깅 서비스를 구축하고 있습니다.

다음 모델이 있습니다.

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 방법은 무엇입니까?

도움이 되었습니까?

해결책

당신이 무엇을 찾고 있는지 확실하지 않지만 여기에 내 제안이 있습니다.

나는 당신이 그 다음 수업에 대한 다른 목적을 가지고 있다고 가정합니다. 그렇지 않으면 나는 그것의 목적을 보지 못합니다.

"올바른 방법"(즉, 완전히 주관적인 방법)은 실제로 다음과 같습니다.

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, 그것에 대해 생각하지 않았으므로 이런 식으로 맞지 않을 것입니다.

따라서 유일한 "좋은"옵션은 첫 번째 예에서와 같이 사용자 클래스를 살펴 보는 것입니다. 내가 볼 수있는 유일한 옵션은 협회 확장 (예를들 수 없음) 또는 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 문을 사용자 정의해야 할 것입니다. 그러나 적어도 사진을 가져와야합니다 :)

다른 팁

Keijro의 배열은 더 잘 작동하지만 다음 테이블이 필요하면 다음과 같이 지정된 SQL 쿼리를 실행할 수 있습니다.

Follow.all(:joins => { :messages, :users }, :conditions => { "follows.follower_id" => current_user.id, "follows.followee_id" => "users.id", "users.id" => "messages.user_id"} )
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top