生の SQL クエリを直接実行する find_by_sql
メソッドの使い方メモ。
使い方
※サンプルコードはドキュメントのものを参考にしています。
基本
SQL のクエリを String として記述し、find_by_sql
に渡すだけ。
query = "SELECT title FROM posts WHERE author_id = 1"
Post.find_by_sql(query)
動的に定義する
値を動的に指定したいときは、その値を ?
として入れたい値を順に配列として渡すか
query = "SELECT title FROM posts WHERE author = ? AND created_at > ?"
Post.find_by_sql([query, author_id, start_date])
シンボルで :hoge
と置いて、ハッシュで値を指定する。
query = "SELECT title FROM posts WHERE author = :author_id AND created_at > :start_date"
Post.find_by_sql([query, { author_id: author_id, start_date: start_date }])
count_by_sql
SELECT
に COUNT(*)
のみを含む SQL 文の結果を返す count_by_sql
というメソッドもある。
実行例
Product.count_by_sql("SELECT COUNT(*) FROM sales s, customers c WHERE s.customer_id = c.id")
注意点
引数に渡したクエリはそのまま実行され、使っている DB に応じて処理が変更されることもありません。
そのため 特定の DB エンジンに依存したクエリが書いてあると、DB を移行しようとしたときに修正を余儀なくされてしまうので、最後の手段であると捉えましょう。
参考
ドキュメント:
https://api.rubyonrails.org/v6.0/classes/ActiveRecord/Querying.html
念の為、クエリを直実行したいときは SQL インジェクションなどに注意
https://railsguides.jp/security.html