はじめに
概要
この記事では、Ruby on Railsフレームワークを使用して、データベース操作の基本であるCRUD(Create, Read, Update, Delete)の各プロセスを実行する方法を学びます。Railsの強力なORM(オブジェクトリレーショナルマッピング)システムであるActiveRecordを活用し、データの作成、読み出し、更新、削除を行うための具体的な手法を紹介します。
各セクションでは、create、new/save、all、find、find_by、where、update、destroyなどのメソッドを用いた効果的なデータ操作の例を詳しく解説し、Railsにおけるデータベース管理の基本を習得することを目指します。
目標
- ActiveRecordを使用してRailsでデータベースのCRUD操作を理解し、実践する。
- データベースでのデータの作成、読み出し、更新、削除のためのメソッドを学ぶ。
- Railsアプリケーションでのデータ管理の基本を習得し、より効率的なデータ操作を実現する。
必要な前提条件・事前準備
Railsでのデータ操作の基本を学ぶためには、いくつかの事前準備が必要です。まず、前章「Railsでのデータベース設計と操作を学ぼう」を完了していることが前提です。この知識は、本章で学ぶ内容を理解する上での基盤となります。また、本章でのデータ操作にはRailsコンソールの使用が伴いますので、その起動方法についても事前に確認しておきましょう。
- 前章「Railsでのデータベース設計と操作を学ぼう」を完了していること
- Railsコンソールの起動方法についての基本的な理解
以下の手順に従って、Railsコンソールの起動方法を確認しましょう。これにより、CRUD操作をコンソール上で実践的に学ぶ準備が整います。
Railsコンソールの起動方法
データ操作は、コンソール上で行います。Railsでは、console
コマンドでコンソールを起動させて、Railsアプリケーションとコマンドラインでやり取りすることができます。
Webにアクセスすることなく、サーバーのデータを変更するときやメソッドを試すときに便利です。内部ではirbが使われているので、同じように操作を行えます。
1
2
rails console
# rails c でも可能
他にもオプションの-sandbox
を付けることで、終了時にコンソールで変更したデータを元に戻すことができます。
1
2
rails console -sandbox
# rails c -s でも可能
上記のコマンドを実行すると、下の画像のようにin sandbox
が表示されます。
コンソールを終了するには、exit
かquit
を実行します。
1
2
3
exit
#もしくは、以下を実行する
quit
今回は、実際にデータベースにデータを反映させていくので、Sandboxモードではなく、通常モードでコンソールを起動させます。
以下のコマンドを実行して、コンソールを起動してください。
1
cd ~/environment/employee_management
1
rails c
上記のコマンドを実行すると、以下のように表示されます。
ActiveRecordによるCRUD操作の基礎
ActiveRecordは、CRUDの機能を提供します。
CRUDとは、Create(作成)・Read(読み込み)・Update(更新)・Delete(削除)の頭文字を繋げた用語で、データ操作の基本となる4つの処理のことでしたね。
SQLでは、CRUDに対応するデータ操作言語のキーワードとしてINSERT
・SELECT
・UPDATE
・DELETE
が用意されており、これらを利用してデータ操作を学習しました。
CRUD | SQL文 | SQL文の説明 |
---|---|---|
Create(作成) | INSERT文 | テーブルにレコードを挿入する |
Read(読み込み) | SELECT文 | テーブルのレコードを抽出する |
Update(更新) | UPDATE文 | テーブルのレコードを更新する |
Delete(削除) | DELETE文 | テーブルのレコードを削除する |
Railsでは、ActiveRecordを通じてCRUD(Create、Read、Update、Delete)に対応する多くの便利なメソッドが提供されています。これにより、開発者はデータベースとのやり取りを効率的に行うことが可能です。
ActiveRecordが提供するメソッドやクラスの使用によって、Railsでは「オブジェクトを操作するようにデータを操作する」ことが可能になります。実際のデータ操作メソッドに入る前に、この基本的なコンセプトをしっかりと理解しましょう。
オブジェクトによるデータ操作
前章で少し触れましたが、ActiveRecordでは「モデルのクラス」と「データベースのテーブル」が1対1で紐付けられます。
例えば、以下のようにモデルのUser
クラスの場合は、データベースのusers
テーブルに紐付きます。
1
2
class User < ApplicationRecord
end
ActiveRecordでは、「モデル」と「テーブル」の間だけでなく、「モデルのインスタンス」と「テーブルのレコード」、モデルのインスタンスの「属性(またはプロパティ)」と「テーブルのカラム」も1対1で対応付けられます。
モデルクラスのインスタンスは、テーブルのレコード1件に対応するオブジェクトになり、オブジェクトのプロパティは、テーブルのカラムに対応します。
Rubyのクラスとインスタンスの章で学習しましたが、インスタンスを生成するには、クラスに対して「newメソッド」を呼び出します。
1
クラス名.new
モデルクラスの場合でも、同じように「newメソッド」を呼び出してインスタンスを生成します。しかし、通常のクラスとは違って生成されたインスタンスは、「テーブルのレコード1件」に対応するオブジェクトになります。
1
2
モデルのクラス名.new
#レコード1件に対応するオブジェクトになる
モデルクラスのインスタンス(オブジェクト)に対して、ActiveRecordが提供するメソッドを利用することで、テーブルにレコードを挿入したり、更新や削除などが行えます。まさにオブジェクトを操作するように、データ操作ができます。
例えば、Userモデルクラスのインスタンスに対して、ActiveRecordが提供するsaveメソッドを呼び出せば、テーブルにデータを挿入することができます。
1
2
3
4
5
# Userモデルのインスタンスをuserに代入する
user = User.new(name: "山田花子", age: 34)
# saveメソッドでインスタンスをデータベースに保存する
user.save
メソッドの箇所で詳しく説明しますが、モデルのクラスに対してnewメソッドを呼び出した時点では、「テーブルのレコード1件」に対応するオブジェクトが生成されただけです。実際にデータベースに保存するのは、saveメソッドが行います。
SQLではINSERT構文を使用して、テーブルに新しいレコードを挿入しましたが、RailsではActiveRecordのお陰で、オブジェクトを操作するようにデータ操作が可能になります。
1
INSERT INTO users(name, age) VALUES('山田花子', 34);
1
2
user = User.new(name: "山田花子", age: 34)
user.save
ちなみにモデルのインスタンスに対してsave
メソッドを呼び出すと、裏側では以下のようなSQL文が発行されます。実際にはINSERT構文を使用して、テーブルにレコードを挿入していることがわかりますね。
1
2
3
4
user = User.new(name: "山田花子", age: 34)
user.save
# INSERT INTO `users` (`name`, `age`, `created_at`, `updated_at`) VALUES ('山田花子', 34, '2023-03-24 07:47', '2023-03-24 07:47'
newメソッドを呼び出した時点で特に指定されてないcreated_at
やupdated_at
の値は、発行されるSQL文により、「レコード作成時に現在の日時を自動的に設定する」ということを確認できます。
ActiveRecordの主要なメソッドとそれぞれのCRUD操作の関係は、次の表にまとめられています。
メソッド | 説明 | CRUD |
---|---|---|
new | クラスのインスタンスを生成する(saveメソッドを使用して保存する) | Create |
save | モデルのインスタンスをデータベースに保存する | Create |
create | モデルのインスタンスの生成と同時にデータベースに保存する | Create |
all | 全てのレコードを取得する | Read |
find | 「ID」に当てはまるレコードを全て取得する | Read |
find_by | 「条件」を指定して最初の1件を取得する | Read |
where | 「条件」に当てはまるレコードを全て取得する | Read |
update | 既存のレコードを引数に指定するプロパティ値に更新する | Update |
destroy | 既存のレコードを削除する | Delete |
destroy_all | 指定した条件のレコードと関連しているレコードをすべて削除する | Delete |
これらのCRUDに対応するメソッドを1つずつ詳しく学んでいきましょう。
CRUDのメソッドってたくさんあるみたい。ちゃんと理解できるかなあ…。
大丈夫、ここでは基本的なメソッドだけをおさえるよ。SQLはすでに学んだから、裏側でどんなSQL文が発行されているかを見ると、メソッドの動作がよく理解できるよ。
データの作成(Create)
Createは、「テーブルにレコードを挿入する」というデータ操作の基本処理を指します。
Railsの場合は、ActiveRecordが提供するsave
メソッド、create
メソッドを利用することで、テーブルにレコードを挿入することができます。
メソッド | 説明 |
---|---|
new | クラスのインスタンスを生成する(saveメソッドを使用して保存する) |
save | モデルのインスタンスをデータベースに保存する |
create | モデルのインスタンスの生成と同時にデータベースに保存する |
createメソッドの使い方
create
メソッドは、モデルのインスタンス生成と同時にデータベースに保存するクラスメソッドです。
Userモデルにnameとageというプロパティがある場合、Userモデルのクラスに対してcreateメソッドを呼び出すと、新しいレコードが1件作成され、データベースに保存されます。
1
モデルのクラス名.create(カラム名1: 値1, カラム名2: 値2)
1
User.create(name: "山田花子", age: 34)
以下をコンソールで実行し、nameカラムの値が"開発"
のレコードをdepartments
テーブルに挿入しましょう。
1
Department.create(name: "開発")
上記を実行すると、以下のように裏側でSQL文が発行されます。SQLの章で学習したようにINSERT構文で、テーブルに新しいレコードを挿入していることがわかりますね。
created_at
やupdated_at
には、現在の日時が自動的に設定されます。
phpMyAdminで確認すると、以下のようにdepartmentsテーブルにnameカラムの値が開発
のレコードが1件挿入されています。また、idも自動的に値が入っていますね。
newメソッドとsaveメソッドの組み合わせ
save
メソッドは、モデルのインスタンスをデータベースに保存します。
createメソッドとは違い、saveメソッドはインスタンスを生成しません。そのため、インスタンス生成を行うnewメソッドとセットで利用します。
1
2
3
4
5
# Userモデルのインスタンスを生成して、userに代入する
user = User.new(name: "山田花子", age: 34)
# saveメソッドでインスタンスをデータベースに保存する
user.save
モデルのクラスに対してnewメソッドを呼び出した時点では、「テーブルのレコード1件」に対応するオブジェクトが生成されただけです。実際にデータベースに保存するのは、saveメソッドが行います。
レコードに挿入する値は、最初のコードのようにnewメソッドの引数にハッシュで一度に指定することもできますし、あとのコードのように指定することもできます。
1
2
user = User.new(name: "山田花子", age: 34)
user.save
1
2
3
4
5
user = User.new
user.name = "山田花子"
user.age = 34
user.save
nameカラムの値が"営業"
のレコードをdepartmentsテーブルに挿入してみます。
まずは、newメソッドを利用して、Departmentモデルのインスタンスを生成します。以下のコードをコンソールに記述し、実行しましょう。
1
department = Department.new(name: "営業")
上記を実行すると、以下のようにDepartmentモデルのインスタンスが生成されます。この時点では、newメソッドの引数で指定したname属性のみ値が設定されており、idやcreated_atとupdated_atの属性値は、いずれもnil
で値が何も入っていない状態です。
続いて、生成したDepartmentモデルのインスタンスをsaveメソッドでデータベースに保存します。以下のコードをコンソールに記述し、実行しましょう。
1
department.save
上記を実行すると、以下のように裏側でSQL文が発行されます。INSERT構文で、テーブルに新しいレコードを挿入していることがわかりますね。
created_at
やupdated_at
には、現在の日時が自動的に設定されます。
phpMyAdminで確認すると、以下のようにdepartmentsテーブルにnameカラムの値が営業のレコードが1件挿入されています。また、idも自動的に値が入っていますね。
そして、Departmentモデルのインスタンスが入るdepartment
をコンソールで実行すると、以下のようにnewメソッドを呼び出した時点では、nil
だった属性値に値が設定されていることがわかります。
idには2という値が設定され、created_atやupdated_atには、saveメソッドを実行した際の日時、つまりレコードを作成した現在の日時が設定されます。
複数レコードの一括挿入
データベースに複数のレコードを一度に挿入する方法はいくつか存在しますが、ここでは配列とハッシュを組み合わせて使用するcreateメソッドによる一括挿入を学習しましょう。
createメソッドでは、1件のレコードをデータベースに挿入することができましたね。
1
モデルのクラス名.create(カラム名1: 値1, カラム名2: 値2)
複数のレコードをデータベースに挿入させるには、配列の要素にハッシュを指定します。
1
2
3
4
5
モデルのクラス名.create([
{ カラム名1: 値1 }, # 1件目のレコード
{ カラム名2: 値2 }, # 2件目のレコード
{ カラム名3: 値3 } # 3件目のレコード
])
employeesテーブルに挿入するデータは、以下の通りです。
id | name | birthday | department_id |
---|---|---|---|
1 |
田中太郎 |
1980-10-22 |
1 |
2 |
山田花子 |
1983-08-20 |
1 |
3 |
高橋一朗 |
1986-06-16 |
2 |
4 |
伊藤晴子 |
1987-10-01 |
1 |
5 |
鈴木二郎 |
1990-01-17 |
2 |
6 |
山口冬子 |
1993-05-12 |
2 |
employeesテーブルに複数レコードを挿入するために、以下のコードをコンソールに記述し、実行しましょう。
1
2
3
4
5
6
7
8
Employee.create([
{ name: '田中太郎', birthday: '1980-10-22', department_id: 1 },
{ name: '山田花子', birthday: '1983-08-20', department_id: 1 },
{ name: '高橋一朗', birthday: '1986-06-16', department_id: 2 },
{ name: '伊藤晴子', birthday: '1987-10-01', department_id: 1 },
{ name: '鈴木二郎', birthday: '1990-01-17', department_id: 2 },
{ name: '山口冬子', birthday: '1993-05-12', department_id: 2 }
])
上記を実行すると、以下のように裏側でSQL文が発行されます。INSERT構文で、テーブルに新しいレコードを6件挿入していることがわかりますね。
phpMyAdminでemployeesテーブルを表示して、createメソッドで指定した6件のレコードがテーブルに挿入されていることを確認しましょう。
データの読み込み(Read)
Readは、「テーブルのレコードを抽出する」というデータ操作の基本処理を指します。
Railsの場合は、ActiveRecordが提供するall
メソッド、find
メソッドなどを利用することで、テーブルのレコードを抽出することができます。
メソッド | 説明 |
---|---|
all | 全てのレコードを取得する |
find | 「ID」に当てはまるレコードを全て取得する |
find_by | 「条件」を指定して最初の1件を取得する |
where | 「条件」に当てはまるレコードを全て取得する |
allメソッド(全レコードの取得)
モデルのクラスに対してall
メソッドを呼び出すと、モデルに対応するテーブルのレコードをすべて取得します。
1
モデルのクラス名.all
例えば、usersテーブルのレコードを全て取得する場合はUser.all
と記述します。
1
User.all
employeesテーブルの全てのレコードを取得してみます。
以下のコードをコンソールに記述し、実行しましょう。
1
Employee.all
上記を実行すると、以下のように裏側でSQL文が発行されます。SQLの章で学習したようにSELECT構文で、テーブルのすべてのレコードを抽出していることがわかりますね。
戻り値には、employees
テーブルの全てのレコードが設定されています。
findメソッド(特定レコードの検索)
find
メソッドは、引数の主キーに対応するレコードを取得するクラスメソッドです。
findメソッドの引数には1つの主キーだけではなく、配列で複数の主キーの値を指定して、レコードを取得することもできます。
1
モデルのクラス名.find(主キー値)
1
モデルのクラス名.find([主キー値1, 主キー値2])
テーブルの主キーは、id
というカラム名がデフォルトで使われます。
例えば、以下のようにUser.find(1)
と指定する場合、Userモデルに対応するusersテーブルの主キー、つまりidの値が1のレコードを取得します。
1
User.find(1)
以下のように指定すると、id
の値が1
と2
のレコードを取得します。
1
User.find([1,2])
employeesテーブルのidの値が4
のレコードを取得してみます。
以下のコードをコンソールに記述し、実行しましょう。
1
Employee.find(4)
上記を実行すると、以下のように裏側でSQL文が発行されます。SELECT構文で、employeesテーブルのidの値が4
のレコードを抽出していることがわかりますね。
戻り値は、取得したデータの値がセットされているEmployeeモデルのインスタンスです。
find_byメソッド(条件付き単一レコードの検索)
find_byメソッドは、引数の条件に当てはまる最初の1件のレコードを取得するクラスメソッドです。
引数の条件は、ハッシュで指定します。
1
モデルのクラス名.find_by(条件)
1
User.find_by(name: '田中太郎')
employeesテーブルのname
の値が'鈴木二郎'
のレコードを取得してみます。
以下のコードをコンソールに記述し、実行しましょう。
1
Employee.find_by(name: '鈴木二郎')
上記を実行すると、以下のように裏側でSQL文が発行されます。SELECT構文で、employeesテーブルのname
の値が'鈴木二郎'
のレコードを抽出していることがわかりますね。
戻り値は、取得したデータの値がセットされているEmployeeモデルのインスタンスです。
whereメソッド(条件検索)
whereメソッドは、引数の条件に当てはまるレコードを全て取得するクラスメソッドです。
1
モデルのクラス名.where(条件)
find_byメソッドの場合は、引数の条件に当てはまる最初のレコードを1件だけ取得しますが、whereメソッドは、条件に当てはまる全てのレコードを取得します。
例えばUser.where(age: 20)
とUser.find_by(age: 20)
のように、引数に同じ条件を指定しても、取得するレコード数は違います。
1
User.where(age: 20)
1
User.find_by(age: 20)
以下のようにUser.where(age: 20)
は、age
が20
のレコードを全て取得します。
employeesテーブルのdepartment_id
の値が2
のレコードをすべて取得してみます。
以下のコードをコンソールに記述し、実行しましょう。
1
Employee.where(department_id: 2)
上記を実行すると、以下のように裏側でSQL文が発行されます。SELECT構文で、employeesテーブルのdepartment_id
の値が2
のレコードを抽出していることがわかりますね。
戻り値には、条件に当てはまるemployeesテーブルの全てのレコードが設定されています。
データの更新(Update)
Updateは、「テーブルのレコードを更新する」というデータ操作の基本処理を指します。
Railsの場合は、ActiveRecordが提供するupdate
メソッドなどを利用することで、テーブルのレコードを更新することができます。
メソッド | 説明 |
---|---|
update | 既存のレコードを引数に指定するプロパティ値に更新する |
saveメソッド(変更内容の保存)
更新対象のオブジェクトを取得すると、オブジェクトのプロパティを変更し、その結果をデータベースに保存できるようになります。
例えば、以下のようにfind_by
メソッドで更新対象のオブジェクトを取得し、nameプロパティ値を'田中太郎'
から'田中航太郎'
に変更します。変更後、save
メソッドを呼び出して、データベースに保存します。
1
2
3
user = User.find_by(name: '田中太郎') #更新対象のオブジェクトを取得
user.name = '田中航太郎' #プロパティを変更
user.save #データベースに保存する
updateメソッドを利用すると、上のコードを短く書けるよ!
updateメソッド(レコードの更新)
updateメソッドを利用する場合も、あらかじめfind
メソッドやfind_by
メソッドなどで、オブジェクトを取得してから更新処理を行います。
updateメソッドの引数にプロパティ名と設定したい値をハッシュで対応付けます。
1
更新対象のオブジェクト.update(プロパティ名: 値)
先ほどのsaveメソッドと同様に'田中太郎'
を'田中航太郎'
に更新する場合は、更新対象のオブジェクトを取得後、以下のようにupdateメソッドの引数を指定します。
updateメソッドを呼び出すと、更新対象のオブジェクトのプロパティを引数の値に更新し、その結果をデータベースに保存します。
1
2
user = User.find_by(name: '田中太郎')
user.update(name: '田中航太郎')
employeesテーブルにある山口冬子さんの生年月日、birthday
の値を1993-05-12
から1993-12-12
に更新してみます。
以下のコードをコンソールに記述し、実行しましょう。
1
2
employee = Employee.find_by(name: '山口冬子')
employee.update(birthday: '1993-12-12')
上記を実行すると、以下のように裏側でSQL文が発行されます。SQLの章で学習したように、既存のレコードのカラムを新しい値に更新するには、UPDATE構文が使用されます。
SET句には変更するカラム名と新しい値、WHERE句にはどのレコードを更新するかを識別する条件が指定されており、id
が6
のレコードのbirthday
を'1993-12-12'
に更新していることがわかりますね。
また、レコードの更新時に現在の日時を設定するupdated_at
の値も自動的に更新されます。データが更新されると、戻り値としてtrue
を返します。
オブジェクトのプロパティ値が更新されていることを確認してみましょう。更新対象のオブジェクトを保持するemployee
をコンソールに記述し、実行しましょう。
1
employee
上記を実行すると、以下のように更新後のbirthday
のプロパティ値は、更新前と比べてupdateメソッドに指定した値に変更されていることがわかりますね。
phpMyAdminを再読み込みして、employees
テーブル内の山口冬子さんのbirthday
が1993-05-12
から1993-12-12
に更新されていることを確認しましょう。
また、updated_at
の値も更新した日時に変更されたかを確かめてみてください。
データの削除(Delete)
Deleteは、「テーブルのレコードを削除する」というデータ操作の基本処理を指します。
Railsの場合は、ActiveRecordが提供するdestroy
メソッド、destroy_all
メソッドなどを利用することで、テーブルのレコードを削除することができます。
メソッド | 説明 |
---|---|
destroy | 既存のレコードを削除する |
destroy_all | 指定した条件のレコードと関連しているレコードをすべて削除する |
destroyメソッド(レコードの削除)
destroyメソッドを利用する場合、あらかじめfind
メソッドやfind_by
メソッドなどで、オブジェクトを取得してから削除処理を行います。
削除対象のオブジェクトに対して、destroyメソッドを呼び出します。
1
削除対象のオブジェクト.destroy
例えば、users
テーブルのname
カラムの値が'田中太郎'
のレコードを削除するには、以下のように、まずオブジェクトを取得します。そして、取得したオブジェクトに対してdestroyメソッドを呼び出し、データベースからレコードを削除します。
1
2
user = User.find_by(name: '田中太郎') #削除対象のオブジェクトを取得する
user.destroy #レコードを削除する
employeesテーブルにあるnameカラムの値が'山口冬子'
のレコードを削除してみます。
以下のコードをコンソールに記述し、実行しましょう。
1
2
employee = Employee.find_by(name: '山口冬子')
employee. destroy
上記を実行すると、以下のように裏側でSQL文が発行されます。SQLの章で学習したように、テーブル内の既存のレコードを削除するには、DELETE構文が使用されます。
phpMyAdminを再読み込みして、employeesテーブルにあるname
の値が'山口冬子'
のレコードが削除されていることを確かめてみましょう。
destroy_allメソッド(一括削除)
モデルのクラスに対してdestroy_all
メソッドを呼び出すと、モデルに対応するテーブルのレコードをすべて削除します。
1
モデルのクラス名.destroy_all
usersテーブルのレコードを全て削除する場合は、User.destroy_all
と記述します。
1
User.destroy_all
以下のコードを上から順番にコンソールで実行し、employees
テーブルのレコードから削除するようにしましょう。
1
Employee.destroy_all
1
Department.destroy_all
phpMyAdminを再読み込みして、departmentsテーブルとemployeesテーブル内のレコードが全て削除されたかを確認しましょう。
この章のまとめ
この章では、Railsでのデータ操作の基礎、特にCRUD(Create、Read、Update、Delete)操作に関する学習を行いました。ActiveRecordを活用した効率的かつ直感的なデータベース操作方法を理解し、実践する技術を習得しました。これにより、Railsアプリケーション開発のための重要な基礎が築かれました。
次の章に進む前に、以下のコマンドを実行して環境をリセットしておきましょう。この章をもう一度学習したい方は、以下のコマンドを実行した後、「ActiveRecordによるCRUD操作の基礎」から取り組んでみてください。
1
cd ~/employee_management
1
rails db:migrate:reset
この章のまとめ
- Railsでは、ActiveRecordを通じてCRUD(Create、Read、Update、Delete)に対応する多くの便利なメソッドが提供される
- これらのメソッドを使用することで、データベースとの効率的なやり取りを行うことができる
この記事で学んだことをTwitterに投稿して、アウトプットしよう!
Twitterの投稿画面に遷移します