在rails中使用activerecord的多个连接

时间:2009-05-04 23:01:06

标签: sql ruby-on-rails activerecord join

我正在构建一个小型的Twitter风格微博服务,用户可以关注其他用户并获取他们的消息提要

我有以下型号:

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 个答案:

答案 0 :(得分:1)

不确定你在寻找什么,但这是我的建议:

我认为你对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类。 我能看到的唯一其他选项是关联扩展(我不能给你一个例子)或者可能使用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语句才能使一切正常运行,但至少您应该得到图片:)

答案 1 :(得分:1)

Keijro的安排会更好,但如果您需要Follow表,那么您可以执行您指定的SQL查询,如下所示:

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