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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27791553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:02:21  来源:igfitidea点击:

Rails: correct way of turning activerecord relation to array?

ruby-on-railsactiverecord

提问by cqcn1991

I was trying to select objects uniq by one attribute, using @videos.uniq{|p| p.author}

我试图通过一个属性选择对象 uniq,使用 @videos.uniq{|p| p.author}

  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

.uniqis not for ActiveRecord_Relation. And the problem is that the query returns a Video::ActiveRecord_Relation, but I need array.

.uniq不是为了ActiveRecord_Relation。问题是查询返回一个Video::ActiveRecord_Relation,但我需要array.

Certainly, this could be achieved by using to_a, but is this elegant?

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

  1. What's the correct way of handling this ?
  2. Is is possible to use .uniqfor activerecord:relation?
  1. 处理这个问题的正确方法是什么?
  2. 可以.uniq用于activerecord:relation吗?

回答by Alejandro Babio

If you need to access to the query result, just use #to_aon ActiveRecord::Relation instance.

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

At rails guidesyou can find on notable changes at Rails 4.0: "Model.all now returns an ActiveRecord::Relation, rather than an array of records. Use Relation#to_a if you really want an array. In some specific cases, this may cause breakage when upgrading." That is valid for other relation methods like :where.

Rails 指南中,您可以找到 Rails 4.0 的显着变化:“Model.all 现在返回 ActiveRecord::Relation,而不是记录数组。如果您确实需要数组,请使用 Relation#to_a。在某些特定情况下,这可能升级时导致损坏。” 这对其他关系方法有效,例如 :where。

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

回答by Prakash Murthy

.uniqdoes not make much sense when it is applied across the full active-record record.

.uniq当它应用于完整的活动记录记录时没有多大意义。

Given that at least one or more of the three attributes - id, created_at, and updated_at- are different for every row, applying videos.uniq{|p| p.author}where videosis a ActiveRecord::Relationincluding all fields, will return all the rows in the ActiveRecord::Relation.

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

When the ActiveRecord::Relationobject has a subset of values, uniqwill be able to figure out the distinct values from them.

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

Eg: videos.select(:author).uniq.countwill give 10 in your example.

例如:videos.select(:author).uniq.count将在您的示例中给出 10。

The difference between ActiveRecord::Relation#uniqand Array#uniqis that the Array version accepts a block and uses the return value of a block for comparison. The ActiveRecord::Relation version of uniq simply ignores the block.

ActiveRecord::Relation#uniq和之间的区别在于Array#uniqArray 版本接受一个块,并使用一个块的返回值进行比较。uniq 的 ActiveRecord::Relation 版本简单地忽略了该块。

回答by user1633220

If you need the records, you can use ActiveRecord::Relation#load

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

Causes the records to be loaded from the database if they have not been loaded already. You can use this if for some reason you need to explicitly load some records before actually using them. The return value is the relation itself, not the records.

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

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

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