【问题标题】:How to find only the users who have posted at least one comment如何仅查找至少发表了一条评论的用户
【发布时间】:2010-01-18 19:41:35
【问题描述】:

我正在使用 Rails 2.3.5。

这是标准情况。表是:users、cmets、user_cmets。我需要找到所有状态为“活动”并至少发表了一条评论的用户。

我知道 cmets 表可以有外键,但这是一个人为的例子。表中有两个用户。有两个厘米。这两个 cmets 都是由第一个用户发布的。

named_scope :with_atleast_one_comment, lambda { {
      :joins => 'inner join user_comments on users.id = user_comments.user_id ' } }


 named_scope :with_active_status, {:conditions => {:status => 'active'} }    

当我执行时

 User.with_atleast_one_comment.with_active_status 

我得到了两条记录。由于两个 cmets 都是由一位用户发布的,因此我只需要一位用户。

解决方法是什么?

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    with_at_least_one_comment 范围的行为与您预期的不同。正如问题中出现的那样,它将为 user_cmets 中的每个条目选择一个用户。这会导致您看到重复的结果。当与 active_users 复合时,您将删除由 with_at_least_one_comment 返回的所有不具有活动状态的记录。

    让我们首先简化有问题的命名范围。 您不需要 lambda,因为没有要采用的参数,并且可以将连接外包给 Active Record,如果给定关联,它将执行内部连接。

    简而言之,这个命名范围将完全按照您的意愿行事。

    named_scope :with_at_least_one_comment, :joins => :user_comments, 
      :group => 'users.id'
    

    【讨论】:

      【解决方案2】:

      指定 :uniq => true 选项以从集合中删除重复项。这与 :through 选项结合使用最为有用。

      【讨论】:

      • ArgumentError: Unknown key(s): uniq if I do named_scope :with_atleast_one_comment, lambda { { :uniq => true, :joins => 'inner join user_cmets on users.id = user_cmets.user_id ' } }
      【解决方案3】:

      如果我没记错的话,实现这一目标的方法很少......
      除非 User.cmets?
      或者另一种方法是在你的控制器中指定一个新方法 最后...
      来自 Emfi 的信息应该有效 试试看吧~

      【讨论】:

      • 您的建议还不错。但他们否定了named_scopes 的优势。这是延迟 ActiveRecord 对象填充直到只选择所需记录的优化。依靠新的控制器方法或除非 user.cmets,需要选择所有填充 AR 对象的用户并丢弃不需要的对象。这将导致非常大的 SQL 查询/响应,在大量使用下会严重减慢,并且可能会导致分页。
      • 是的......你是对的~我的错不在乎应用程序的性能所以......最后的结论是 Emfi 的答案是最好的......
      猜你喜欢
      • 2020-12-11
      • 2015-05-13
      • 1970-01-01
      • 2014-08-12
      • 2020-07-17
      • 1970-01-01
      • 1970-01-01
      • 2021-07-03
      • 2018-03-16
      相关资源
      最近更新 更多