arait-code’s RC

もうすぐエンジニア転職して2年になります。

railsで生SQLをスッキリ使う方法

Railsで生SQLを使う方法と言えば

ActiveRecord::Base.sanitize_sql_array

を使用するかと思いますが頻繁に使用するためmoduleとして 切り出して使う方法を紹介します。

module Sanitizable
  def sanitize_sql(sql, placeholders)
    squish_sql = sql.split("*/").map { |str| str.squish.gsub(%r(/\*.*\*), '') }.join(' ')

    ActiveRecord::Base
      .sanitize_sql_array([squish_sql, placeholders])
  end
end

squish_sqlはgsubにて除去する記述になりログにコメントが出なくなり見やすくなります。

このモジュールを作成してSQLを使いたいserviceクラスやformクラスにて

include Sanitizable 

としてやりSQLを変数などに入れて別途定義したplaceholdersと一緒に

def set_hoge
  sql = sanitize_sql(HOGE_SQL, placeholders)

  @fuga = Model名
           .from("#{sql} as hoge")
end

private

def placeholders
  {
    id: hoge_id,
    date: date
  }
end

またSQLの規模が大きい場合別途.sqlファイルなどを作成し上記の様な形で渡すことも出来ます。

TEST_SQL = IO.read(File.expand_path('./index_form/test.sql', __dir__))

定数にするのは実行回数ではなく、クラスロード時に一回だけ処理になる=IOの負担を軽減するためです。