2

今天我学习了如何使用 Arel 来构建需要使用标准 ActiveRecord 的 SQL 片段的 SQL 查询。到目前为止,我见过的所有 Rails 应用程序(充其量)都有包装原始 SQL 的作用域,如下所示:

# in class Post
scope :select_comment_count, -> {
  join_comments.select('COUNT(comments.id)')
}
scope :join_comments, -> {
  joins("LEFT OUTER JOIN comments ON comments.post_id = posts.id AND comments.is_most_recent_edit = '1'")
}

两者都可以在 Arel 中重写,无需使用 SQL。

我的第一个问题是,在 SQL 片段上使用 Arel 的具体优点和缺点是什么,为什么似乎每个应用程序和每个 RoR 开发人员都忽略了 Arel?

此外,默认情况下,我的 Arel 似乎非常混乱,部分原因是我的 Arel 必须了解我的外键名称:

scope :select_comment_count, -> {
  comments = Comment.arel_table
  joins_comments.select(comments[:id].count)
}

scope :join_comments, -> {
  posts = Post.arel_table
  comments = Comment.arel_table

  # Bypasses ActiveRecord associations completely.
  # We're using Arel to generate the above SQL
  # Isn't this exactly the same as using Raw SQL, but slower?
  # In some cases we would still lose DB independence,
  # for instance if we did an update_all with a join in MySQL
  # (not allowed in PostgreSQL)

  sql = posts.
    join(comments, Arel::Nodes::OuterJoin).
    on(
          (comments[:post_id].eq(posts[:id])). # Here we duplicate the knowledge of how our foreign key names relate to our associations
      .and(comments[:is_most_recent_edit].eq(false))
    ).join_sql

  joins(join_sql)
}

是否有任何好的工具或库可以统一 ActiveRecord 查询界面和更多 Arel,或者有什么好的技术可以让您的 Arel 保持简单和美观?我真的很想使用 Arel,但是以一种利用 ActiveRecord 关联的力量的方式,并且感觉不像是一个完全独立的 API 或 SQL 之上的额外复杂层。

4

1 回答 1

1

首先,第一个查询可以写成comments.count,当然?

当您回顾问题中的代码时,人们倾向于更频繁地使用 SQL 的原因就很清楚了。SQL 更简单,更易于阅读。

虽然 SQL 的实现存在差异,但值得记住的是,SQL 是一种标准,因此其中很多也适用于许多不同的数据库服务器。

另一方面,您可能对Squeel gem 感兴趣。

于 2013-06-24T20:01:18.747 回答