1

我怎样才能得到相同的结果,但是就像 posts 方法是一个简单的关联?
我想这样做:“user.posts.active”。是定义 :finder_sql 的最佳解决方案吗?

class User < ActiveRecord::Base
    has_many :created_posts, class_name: Post.name, foreign_key: :creator_id
    has_many :updated_posts, class_name: Post.name, foreign_key: :updater_id

    def posts
        (created_posts + updated_posts).flatten.uniq
    end
end
4

1 回答 1

3

您可以通过让 SQL 只为您提供唯一列表来提高效率,而不是加载两组帖子然后在 Ruby 中对它们进行唯一化。

class User < ActiveRecord::Base
  def posts
    Post.where(["creator_id = ? OR updater_id = ?", self.id, self.id])
  end

  ...
end

这样做更有效的原因是因为它发出带有一组响应行的单个 DB 查询,从不返回重复项,然后 ActiveRecord 只为该组行实例化 Ruby 对象。

作为比较,您原始问题中的方法发出两个数据库查询,每个查询创建一个User对象数组,然后组合这两个数组,然后删除重复项。额外的对象初始化,然后是数组的组合,然后是删除重复项所需的组合数组上的迭代——所有这些都组合在一起——是大部分开销发生的地方。

与所有此类优化一样,如果您正在处理一个非常小的数据集,则性能差异可能可以忽略不计,但是在这种情况下,单查询、单组响应方法非常聪明。

附带说明...

使用定义的关系,如果两个用户一个接一个地更新同一个帖子,不仅最近的用户会将他们的 id 分配给updater_id? 那是你的意图吗?

根据您的应用程序的设计,最好自己记录更新,这样所有编辑过给定帖子的用户都会在他们的updated_posts.

于 2013-05-15T17:02:57.737 回答