Ruby on Railsでは通常、ActiveRecordを通じてデータベースを操作しますが、複雑なクエリや特殊な処理が必要な場合にはSQLを直接実行することもできます。この記事では、RailsでSQLを直接操作する方法と、ActiveRecordの基本的なCRUD操作、マイグレーションについて解説します。
基本的な使い方
ActiveRecord::Base.connection.executeメソッドを使って、SQLクエリを直接実行できます。
class PostsController < ApplicationController
def index
sql = "SELECT * FROM companies"
@companies = ActiveRecord::Base.connection.execute(sql)
end
end<% @companies.each do |company| %>
<div><%= company['name'] %></div>
<% end %>executeメソッドの戻り値はデータベースアダプタに依存しますが、通常はハッシュの配列のような形でアクセスできます。カラム名をキーとして各行のデータを取得します。
パラメータ付きSQL(SQLインジェクション対策)
SQLを直接書く場合、ユーザー入力をそのまま文字列連結するとSQLインジェクション攻撃のリスクがあります。必ずプレースホルダーを使用してください。
# 危険な書き方(絶対にやらないこと)
sql = "SELECT * FROM users WHERE name = '#{params[:name]}'"
# 安全な書き方(プレースホルダーを使用)
sql = "SELECT * FROM users WHERE name = ?"
results = ActiveRecord::Base.connection.exec_query(sql, "SQL", [params[:name]])ユーザー入力を直接SQLに埋め込むと、悪意のあるSQLが実行される可能性があります。必ずプレースホルダー(?)やバインド変数を使用してSQLインジェクションを防いでください。
ActiveRecordによるCRUD操作
通常のデータ操作はActiveRecordのメソッドを使うのが推奨されます。SQLを直接書くよりも安全で読みやすいコードになります。
# Create(作成)
company = Company.new(name: "テスト会社", address: "東京都")
company.save
# Read(読み取り)
companies = Company.all # 全件取得
company = Company.find(1) # IDで検索
results = Company.where(name: "テスト会社") # 条件で検索
# Update(更新)
company = Company.find(1)
company.update(name: "新しい会社名")
# Delete(削除)
company = Company.find(1)
company.destroyActiveRecordは内部でSQLを自動生成してくれるため、開発者がSQLを意識する必要がありません。また、SQLインジェクション対策も自動的に行われます。
テーブルの作成(マイグレーション)
Railsではデータベースのテーブル構造をマイグレーションファイルで管理します。テーブルの作成はモデルの生成コマンドで行います。
rails generate model Company name:string address:string phone:stringこのコマンドにより、マイグレーションファイルとモデルファイルが自動生成されます。マイグレーションを実行してテーブルを作成します。
rails db:migrateカラムの追加・変更
既存テーブルにカラムを追加するには、マイグレーションファイルを生成して実行します。
rails generate migration AddPhoneToCompanies phone:string
rails db:migrateclass AddPhoneToCompanies < ActiveRecord::Migration[7.0]
def change
add_column :companies, :phone, :string
end
endマイグレーションを元に戻したい場合は、rollbackコマンドを使います。
rails db:rollbackSQLを直接実行するのは、ActiveRecordでは表現できない複雑なクエリ(複数テーブルの結合や集計関数など)が必要な場合に限定しましょう。通常のCRUD操作はActiveRecordを使うのが安全で効率的です。
まとめ
ActiveRecord::Base.connection.execute(sql)でSQLを直接実行できる- SQLインジェクション対策としてプレースホルダー(
?)を必ず使用する - 通常のCRUD操作はActiveRecordのメソッド(
find、where、create等)を使う - テーブル構造はマイグレーションで管理する
rails db:migrateでマイグレーション実行、rails db:rollbackで元に戻す- SQL直接実行はActiveRecordで対応できない場合に限定する