今天我学习了如何使用 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 之上的额外复杂层。