今日、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'")
}
どちらも、SQL を使用せずに Arel で書き直すことができます。
私の最初の質問は、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 上の複雑な追加レイヤーのようには感じません。