множественные объединения с использованием activerecord в рельсах - PullRequest
1 голос
/ 05 мая 2009

Я создаю небольшой сервис микроблогов в стиле твиттера, где пользователи могут следить за другими пользователями и получать их сообщения

У меня есть следующие модели:

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 сделать это?

Ответы [ 2 ]

1 голос
/ 08 мая 2009

Расположение Кейро будет работать лучше, хотя, если вам нужна таблица Follow, вы можете выполнить указанный вами SQL-запрос следующим образом:

Follow.all(:joins => { :messages, :users }, :conditions => { "follows.follower_id" => current_user.id, "follows.followee_id" => "users.id", "users.id" => "messages.user_id"} )
1 голос
/ 05 мая 2009

Не уверен, что вы ищете, но вот мое предложение:

Я предполагаю, что у вас есть другие цели для этого класса Follow, иначе я не вижу цели этого.

«Правильный путь» (т. Е. Мой полностью субъективный способ) сделать это на самом деле был бы примерно таким:

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-оператор, чтобы все заработало, но по крайней мере вы должны получить картинку :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...