Rails/Arel:选择所有记录作为 ActiveRecord::Relation

Posted

技术标签:

【中文标题】Rails/Arel:选择所有记录作为 ActiveRecord::Relation【英文标题】:Rails/Arel: Selecting all records as an ActiveRecord::Relation 【发布时间】:2011-08-01 12:58:23 【问题描述】:

在 Rails 中使用 Arel - 我正在寻找一种创建 ActiveRecord::Relation 的方法,它可以有效地生成 SELECT * FROM table,我仍然可以进一步操作。

例如,我有一个分成多个类别的模型,我通过以下方式返回这些类别的计数:

relation = Model.where(:archived => false) # all non-archived records
record_counts = 
  :total => relation.count,
  :for_sale => relation.where(:for_sale => true).count
  :on_auction => relation.where(:on_auction => true).count

这很好用,并且具有向 mysql 发起 COUNT 查询的优势,而不是实际选择记录本身。

但是,我现在需要在计数中包含存档记录,但 relation = Model.all 的结果是 Array,我正在寻找 ActiveRecord::Relation

我能想到的唯一方法是model.where(model.arel_table[:id].not_eq(nil)),它有效,但似乎有点荒谬。

任何人都可以对此有所了解吗?

【问题讨论】:

【参考方案1】:

试试relation = Model.scoped。这将为您提供关系而不是实际结果。

【讨论】:

Model.scoped 在 Rails 4.X 中已弃用。查看其他答案。 再次感谢,我现在接受了 Kyle 的回答,因为它提供了不同 Rails 版本的更完整图片。【参考方案2】:

对于 Rails 4.1 及更高版本:Model.all 返回一个关系(以前没有)

对于 Rails 4.0:Model.where(nil)

对于 Rails 3.x:Model.scoped

【讨论】:

在 Rails 4.0.13 上,Model.all 返回一个关系,Model.scoped 已弃用。【参考方案3】:

你会想要:

relation = Model.scoped

如果你看到什么是关系,它实际上是一个ActiveRecord::Relation

正如您在此页面中看到的那样:

http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html#method-i-scoped

上面写着:

匿名作用域往往很有用 当程序生成复杂时 查询,其中传递中间 价值(范围)大约是一流的 对象很方便。

【讨论】:

真正需要scoped 的唯一时间是您想要对所有记录采取行动,例如Model.all。只需执行 Model.where(:archived => false) 就已经返回了 ActiveRecord::Relation 对象。

以上是关于Rails/Arel:选择所有记录作为 ActiveRecord::Relation的主要内容,如果未能解决你的问题,请参考以下文章

Rails Arel查询,在现在之前获取列一定的持续时间

始终选择表中所有记录的 WHERE 子句

从表中选择所有或仅特定的行

MySQL - 选择匹配所有值的记录[重复]

Toad 问题:Oracle 类型作为显示所有记录的表中列的数据类型

选择与 Hadoop 用户列表匹配的记录