トップイメージ

Railsで生のSQLを使いたいんだけど・・・

RailsにはORMの機能があるため、しっかりとテーブル(モデル)間の関連付けをしておけば、ちょっとしたWHERE文相当の値であれば、SQL無しで値を取得してくることができます。

しかし、実際の現場ではTableを結合したり、viewを作ったり、TableをUNIONして見たり、生のSQLを流したくなることがあります。


2019-10-13追記

確かに生SQLを流したいことはありますが、多くの場合ActiveRecord使った方が早いです。


今回はSQLを流す方法を備忘録としてまとめています。

find_by_sqlメソッドを使う

次のような例。はっきり言って、このレベルならSQLを書かずに、モデルのリレーションで取得できるけど、一例として。

#コントローラー
def getSql
    #sql文を下のようにヒアドキュメントで用意
    sql=<<-SQL
        SELECT
          m.id,m.group_no,m.group_name,
          us.stard_day,
          us.end_day
        FROM
          users u
        INNER JOIN
          user_syozoku us
        ON
          u.id = us.user_id
        INNER JOIN
          m_syozokus m
        ON
          us.m_group_id = m.id
        WHERE
          account = '#{params[:account]}'
        ORDER BY 
          group_no
    SQL
        m_syozokus = MSyozoku.find_by_sql(sql)
        render :json => m_syozokus
      end

ActiveRecordBase.conectionを使う

テーブルを結合したり、ユニオンしたり、複雑な処理をSQLで描く場合、次のような方法もあるみたい、

def getSql

        sql = ""
        sql += " SELECT"
        sql += "   tablea.id "
        sql += "   , tablea.kanri_no             AS kanrino "

        #(略)ちなみに下記のように、送付されるパラメータから判断して処理を分岐することもできる
        sql += "   AND simei = #{params[:simei]}" if params[:simei].present?
        # (略)
        conect = ActiveRecord::Base.connection
        results = conect.execute(sql)

        #この後、結果を加工してデータをユーザーに返すなり、jsに渡すなり、後続の処理を

end

2019-10-13追記

ActiveRecord使った方が早いです。 モデルにアソシエーションを定義して、実行した方が良い。

動的に条件を変えたい場合でも、条件部分を変数化して、動的に変えてあげれば良いだけですね・・・

モデルへのアソシエーション定義方法や、テーブル間の結合などはこちらの記事です。

condition = "where 0 = 0"
condtion += " and simeis like '%params[:simei]% '  " if params[:simei].present?
#ユーザーがviewのフォーム等で動的に条件を変更してくる場合など、上のように条件を追記してあげる
Tables.joins(結合したいテーブル).select(condition)

結構自由にSQLを飛ばせる

まぁ、これに関しては、生のSQLを流す必要があるのか、そもそもORMだけでいけるのではないか?

など様々ご意見があられるかと思いますが、あくまで一例としてご覧くださいませ。


2019-10-13

生SQLだと、どうしてもコードが長くなったり、テーブル定義の変更があったら、SQL書いた全ての箇所を結構修正しなければならないとか、問題があります。もし可能なら、ActiveRecord使ってsql流した方が、工数は下がるかと思います。

ただし、ActiveRecordのメソッドでどのような、SQLが流れているか、確認しながら開発を進めましょう。