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'")
}

どちらも、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 上の複雑な追加レイヤーのようには感じません。

4

1 に答える 1

1

まず、その最初のクエリは次のように記述できますcomments.count

人々が SQL をより頻繁に使用する傾向がある理由は、質問のコードを振り返ると非常に明確です。SQL はよりシンプルで読みやすくなっています。

SQL の実装には違いがありますが、SQL は標準であることを覚えておく価値があります。したがって、SQL の多くはさまざまなデータベース サーバーでも機能します。

一方、Squeel gem に興味があるかもしれません。

于 2013-06-24T20:01:18.747 に答える