0

在The Rails Tutorial 2nd edition 的第 11 章的清单 11.45from_users_followed_by中,类的类方法Micropost定义如下:

class Micropost < ActiveRecord::Base
...
  def self.from_users_followed_by(user)
    followed_user_ids = "SELECT followed_id FROM relationships
                         WHERE follower_id = :user_id"
    where("user_id IN (#{followed_user_ids}) OR user_id = :user_id", 
          user_id: user.id)
  end
end

在本章的脚注 13中,有一个指向此博客文章的链接,其中说如果要创建子选择字符串,可以将 ActiveRecord 内部方法construct_finder_sql与该方法一起使用。send因此,我尝试将followed_user_ids字符串替换为:

followed_user_ids = Relationship.send(:construct_finder_sql,
                                      select: "followed_id",
                                      conditions: { follower_id: :user_id })

唯一的问题是它在 Rails 3 中construct_finder_sql贬值了,所以我不知道我写的内容是否正确,无论如何我都不能使用它。:user_id那么,是否有一种 Rails 3 方法可以在这种情况下使用 ActiveRecord(最好仍然使用参数)创建子选择字符串?

4

1 回答 1

1

您可以将您的 seb-select 构建为单独的查询,然后用于to_sql获取 SQL:

def self.from_users_followed_by(user)
  followed = Relationship.select(:followed_id)
                         .where(:follower_id => user.id)
                         .to_sql
  where("user_id in (#{followed}) or user_id = :user_id", :user_id => user.id)
end

诸如M.select(...).where(...)仅构建ActiveRecord::Relation实例和逐个构建查询之类的事情,在您要求某些结果(以某种方式或其他方式)之前,不会将任何内容发送到数据库。因此,您可以使用 AREL 的东西来构建查询,然后to_sql获取 SQL 版本。

于 2012-06-10T18:20:49.530 回答