Rails:将activerecord关系转换为数组的正确方法?

时间:2015-01-06 03:14:51

标签: ruby-on-rails activerecord

我试图使用@videos.uniq{|p| p.author}

按一个属性选择对象uniq
  time = Time.new(2014, 12)
  start_time = time.beginning_of_month
  end_time = time.end_of_month

  videos = Video.where("created_at > ? AND created_at < ?", start_time, end_time).where("likes > ?", 15)
  selected_videos = videos.uniq{|p| p.author}
  puts videos.count, videos.class, selected_videos.count 
 #=> 23, Video::ActiveRecord_Relation, 23

  videos_first = videos.first(23)
  selected_videos = videos_first.uniq{|p| p.author}
  puts videos_first.count, videos_first.class, selected_videos.count
  #=> 23, array, 10

.uniq不适用于ActiveRecord_Relation。问题是查询返回Video::ActiveRecord_Relation,但我需要array

当然,这可以通过使用to_a来实现,但这是优雅的吗?

  1. 处理此问题的正确方法是什么?
  2. 是否可以.uniq使用activerecord:relation

3 个答案:

答案 0 :(得分:36)

如果您需要访问查询结果,只需在ActiveRecord :: Relation实例上使用#to_a

rails guides,你可以在Rails 4.0上找到值得注意的变化:“Model.all现在返回一个ActiveRecord :: Relation,而不是一个记录数组。如果你真的想要一个数组,请使用Relation#to_a。在某些特定情况下,升级时可能会导致破损。“这适用于其他关系方法,例如:where。

 selected_videos = videos.to_a.uniq{|p| p.author}

答案 1 :(得分:3)

在整个活动记录记录中应用

.uniq时没有多大意义。

鉴于三个属性中的至少一个或多个 - idcreated_atupdated_at - 对于每一行都不同,将videos.uniq{|p| p.author}应用于{{1 }}是包含所有字段的videos,将返回ActiveRecord::Relation中的所有行。

ActiveRecord::Relation对象具有值的子集时,ActiveRecord::Relation将能够从中找出不同的值。

例如:uniq将在您的示例中给出10。

videos.select(:author).uniq.countActiveRecord::Relation#uniq之间的区别在于Array版本接受一个块并使用块的返回值进行比较。 uniq的ActiveRecord :: Relation版本只是忽略了块。

答案 2 :(得分:2)

如果需要记录,可以使用ActiveRecord :: Relation#load

如果尚未从数据库中加载记录,则导致这些记录。如果出于某种原因需要在实际使用之前明确加载某些记录,则可以使用此方法。返回值是关系本身,而不是记录。

https://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-load