我正在构建一个小型的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方式是什么?
答案 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"} )