Rails 3.0 中的 Arel 到底是啥?

Posted

技术标签:

【中文标题】Rails 3.0 中的 Arel 到底是啥?【英文标题】:What exactly is Arel in Rails 3.0?Rails 3.0 中的 Arel 到底是什么? 【发布时间】:2011-02-15 18:12:04 【问题描述】:

我知道它是 ActiveRecord 的替代品,并且它使用对象而不是查询。

但是……

为什么这样更好?

对象/查询会“更容易”创建吗?

它会带来更高效的 SQL 查询吗?

它将与所有主要数据库兼容吗? - 我想会的。

使用存储过程会更容易/更难吗?

【问题讨论】:

【参考方案1】:

Rails 3.0 中的 Arel 到底是什么?

它是关系查询运算符代数的对象模型。

我知道它是 ActiveRecord 的替代品

不,不是。它是字符串中手工制作 SQL 查询的替代品。它是一个常见的查询层,作为 ActiveRecord 的基础,但它也可以用作 DataMapper 的基础。

如果它是任何东西的替代品,那就是 Ambition 的替代品。或者,您可以将其视为 LINQ 标准查询运算符或 Python 的 SQLAlchemy 的 Ruby 版本。 (事实上​​,作者明确引用了 LINQ 和 SQLAlchemy 作为灵感。)

或者,您可以将其视为named_scopes 的替代品。事实上,ARel 几乎实现了“每个查询都是named_scope”的想法。而且,whaddayaknow:两者都是同一个人写的。

并且它使用对象而不是查询。

不,它使用对象 as 查询。

为什么这样更好?

Ruby 是一种面向对象的语言,而不是一种面向字符串的语言。出于这个原因单独,将查询表示为对象而不是字符串是有意义的。为查询构建适当的对象模型而不是对所有事物都使用字符串,与为会计系统构建适当的对象模型而不是对所有事物都使用字符串所带来的好处几乎相同。

另一个很大的优势是,ARel 实现了查询运算符的实际代数。换句话说,ARel 知道构建和组合查询的数学规则。如果连接两个字符串,每个字符串都包含一个有效的 SQL 查询,那么结果可能不会是一个有效的 SQL 查询。或者,更糟糕的是,它一个有效的 SQL 查询,但它没有意义,或者它所做的事情与你认为的完全不同。这在 ARel 中永远不会发生。 (这就是我在下面链接到的文章的含义,即“在合成下关闭”。)

对象/查询会“更容易”创建吗?

是的。例如,正如我上面提到的,从更简单的部分构造更复杂的查询要容易得多。

它会带来更高效的 SQL 查询吗?

是的。 ARel 拥有适合查询的对象模型这一事实意味着它可以在生成实际 SQL 查询之前很久就对这些查询执行优化。

它将与所有主要数据库兼容吗? - 我想会的。

是的。事实上,我在上面总是谈到 SQL,但实际上关系查询代数可以为几乎所有内容生成查询。同样,以 LINQ 或 Ambition 为例:两者都可以使用相同的语法查询 SQL、LDAP、ActiveResource、CouchDB、Amazon、Google 等。

关于 ARel 是什么以及 Nick Kallen 为何写作的最佳讨论可能是他本人的文章Why Arel? by Nick Kallen。注意:本文包含一些温和的数学和计算机科学术语,但这正是重点:ARel 在数学和计算机科学方面有一些坚实的基础,正是这些基础赋予了它强大的特性。

【讨论】:

优秀的答案。我已经阅读了您发布的链接,并且大部分时间都在关注它。事实上,comp sci 部分是有道理的,但它是如何合并到 Rails 中的,这是我遇到问题的地方。对我来说,它取代了手工制作的 SQL(或其他)更有意义,因此 AR 在 3.0 中构建在它之上。对于应该更了解的人,我得到了不同的印象,这个答案对上述每个问题的简单而准确的解释非常出色。 我确实有一个后续问题。你上面提到了LDAP、AMZ等,我假设目前(基于github上的rails/arel)ARel没有那个能力,只是潜力?即直到有人实施该部分。不过,这听起来确实非常令人兴奋。 @Will - 我认为您将不得不等待有人开发这些更有趣的功能。或者自己尝试一下,你需要吗? @DaveNewton:显然,它已经消失了。周围有一些缓存的副本,例如bmark.us/bmark/readable/913ff84fc0dcdc 这里是the internet archive's version【参考方案2】:

不幸的是,ARel 直接与生成 SQL 相关联,因此不适合 DataMapper 的需求。

我想说的是,ARel 是 ActiveRecord 的显式查询模型,它为 RDBMS 生成和优化 SQL 查询。

另一方面,DataMapper 是真正的数据映射器,并且已经可以与非关系数据存储进行交互。未来 DataMapper 可能会包含一个名为 Veritas 的单独库,旨在为来自任何数据存储的数据提供关系功能,而不仅仅是 RDBMS。

【讨论】:

我是DataMapper的维护者,knowtheory说的是真的。 ARel,在当前的实现中,不能在 DataMapper 下使用,因为它只提供了使用 DM 支持的 40 多个数据存储所需的功能的子集。恕我直言,当前的实现与 SQL 生成紧密耦合,并且需要大量工作来修复 API/内部以使用与 RDBMS 大不相同的数据存储。 ARel 向前迈进了一步,但目前它不能为 ActiveRecord 奠定基础。【参考方案3】:

Rails 3 中的 Arel 生成关系对象,在您需要之前不会查询数据库。效率更高。

它也更自然(一旦你习惯了它),这确实是 Rails 的强大力量。

【讨论】:

【参考方案4】:

实际上我已经开始了一个关于 ActiveRelation 的视频系列。

第一篇通用教程可以查看http://Innovative-Studios.com/#pilot

【讨论】:

以上是关于Rails 3.0 中的 Arel 到底是啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Arel(大概)创建一个不影响 Rails 3 中的查询的 ActiveRecord 范围?

Arel 中的嵌套查询

如何使用ARel对子查询进行连接?

Arel + Rails 4.2 导致问题(绑定丢失)

Arel、联接和 Rails 查询

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