获取一系列独特的ActiveRecord对象

时间:2015-10-08 16:31:00

标签: ruby-on-rails

在我的应用中,每个帖子都有很多消息,消息属于帖子和用户。

所以现在我正试图通过下面的代码获得一组包含唯一用户的消息。但在我看来,阵列仍然是相同的,并不是唯一的。

以下是代码:

<% post.messages.uniq{|x| x.user_id}.each do |m| %>
   ...
<% end %>

2 个答案:

答案 0 :(得分:2)

我认为post是ActiveRecord对象,messages是该类的has_many关系。

致电post.messages时,您不会立即获得阵列。相反,Rails首先创建一个ActiveRecord::Relation对象,其中包含您刚刚执行之前构建的查询。这允许您链接查找程序方法(例如whereselect,...)并在将查询发送到数据库执行之前构建完整查询。

现在,由于您没有数组,因此其方法可以与Array方法不同地运行(并接受不同的参数)。在这种情况下,uniq方法是distinct的别名,它指示将查询创建为DISTINCT。由于您尚未处理实际的对象数组,因此使用块进行过滤仍然无法使用。

为了解决这个问题,您有两种选择:

  • 您可以强制ActiveRecord运行查询并使用to_a方法返回一个数组,然后您可以在上面尝试使用数组的uniq方法和块:

    post.messages.to_a.uniq { |x| x.user_id }
    
  • 您可以创建适当的查询,仅返回实际需要的数据。在这种情况下,这可能具有挑战性,因为所需的SQL可能相当复杂,并且ActiveRecord的查询生成器可能不支持(并且这将由手工创建)。有关如何创建适当查询的详细信息,请参阅this question

答案 1 :(得分:0)

我认为已弃用的.uniq_by方法可行。该文档建议使用Array.uniq,但它不一样。 (Array.uniq忽略给定的块)

如果您不想使用.uniq_by,请尝试以下操作: post.messages.group(:user_id)