この記事でわかること
・Railsモデルの基本操作について。
- ・Railsモデルの基本操作について。
モデルを作成する
まずは、モデルを以下のコマンドで作成します。rails generate model <model-name> <データ名:データ型> <データ名:データ型>
rails generate model User name:string email:string
すると以下のようなコードが表示されます。
invoke active_record
create db/migrate/20221226012605_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
マイグレーション
モデルをrails generateコマンドで作成するとマイグレーションファイルが作成されます。class CreateUsers < ActiveRecord::Migration[6.0]
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
マイグレーションファイルの中にはchangeメソッドが定義されています。このマイグレーションというのは、データベースの変更を定義するもので、マイグレーションを実行することで、データベースに変更を加えることができます。
このファイルが生成されている時点では、マイグレーションは実行されていません。
ちなみに、このファイルにはusersにデータとしてstring型のname属性とemail属性を追加、さらにタイムスタンプを追加することが記述されています。
このファイルを確認したら早速マイグレーションを以下のコードで実行します。
rails db:migrate
これにより、development.sqliteというファイルが作成されます。
このファイルを確認すると、データベースが作成されています。(VSCodeだとファイルの中身を見ることができないので、 DB Browser for SQliteというWebアプリを使用して中身を確認します。↓↓)
これで、実際にデータベースを操作していく準備が整いました。
基本操作(作成、更新、削除)
ユーザーオブジェクトを作成する
Railsでは基本的なデータベースの操作をRailsのメソッドを使用することで行うことができます。例えば、新しいデータを作成したいときは以下のようにコマンドを打ちます。ここでは、rails consoleを使用することにします。オプションで--sandboxをつけることで、行った変更などが実際には反映されずに、コンソールを閉じた瞬間に削除されます。
$rails console --sandbox
以下のコマンドではUserオブジェクトを作成しています。Userオブジェクトには四つの属性がありますが、それぞれには何も入れていませんので、返り値はnilになっています。
>> User.new
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil>
また、以下のコードのように属性に値を代入することもできます。
user = User.new(name: "Katsuki Sanada", email: "katsuki@example.com")
=> #<User id: nil, name: "Katsuki Sanada", email: "katsuki@example.com",
created_at: nil, updated_at: nil>
オブジェクトの有効性を確かめる
ここまででUserオブジェクトを作成し、それをuserに代入しています。このUserオブジェクトが有効性があるかどうかを確かめるコードがいかになります。#name:とemail:が空でないオブジェクト
user = User.new(name: "Katsuki Sanada", email: "katsuki@example.com")
=> #<User id: nil, name: "Katsuki Sanada", email: "katsuki@example.com",
created_at: nil, updated_at: nil>
> user.valid?
=> true
#データが空のオブジェクト
> user2 = User.new
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil>
>user2.valid?
=>true
valid?メソッドでレシーバー(メソッドの対象:今回はuser)に対して有効性を確かめることができます。この有効性というのはuser.rbで定義されています。デフォルトではuser.rbは以下のようになっています。
class User < ApplicationRecord
end
ここには有効性に関する定義がまだされていないので、先ほどのコードではuser,user2に格納されているデータの有無や数に関わらずvalid?メソッドはtrueを返り値として返します。
例えば、user.rbに以下のようにコードを追加したとします。
class User < ApplicationRecord
validates :name, presence: true
end
validatesはrailsのメソッドで、どんなデータを有効とするかに関する定義を行うことができます。ここでは、:nameというデータについての定義を行っています。presence:は「空ではない」という意味で、引数にtrueが書いてあるので、この場合は「:nameというデータが空ではないとき、そのデータは有効である。」という意味になります。
このように定義すると、先ほどのコードに対するvalid?メソッドの返り値が以下のように変わります。
#:nameが空でないオブジェクト
>user.valid?
=>true
#:nameが空のオブジェクト
>user2.valid?
=>false
有効性に関する知識はテストの際にとても重要になるのでここで押さえておきましょう。
データベースにデータを保存する。
今まで、User.newでデータを作成してきましたが、これだけだとまだデータベースにデータを保存できていません。なので、データをしっかりと保存しておきましょう。#Userオブジェクトを作成してuserに代入
>user = User.new(name: "Katsuki Sanada", email: "katsuki@example.com")
=> #<User id: nil, name: "Katsuki Sanada", email: "katsuki@example.com",
created_at: nil, updated_at: nil>
#userに代入されたデータをデータベースに代入
>user.save
User Create (1.9ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "Katsuki Sanada"], ["email", "katsuki@example.com"], ["created_at", "2022-12-26 08:14:27.024740"], ["updated_at", "2022-12-26 08:14:27.024740"]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true
>=true #保存に成功するとtrueを返す。
ちなみに、上記のコードではオブジェクトの作成とデータのデータベースへの保存を分けていますが、createメソッドを使うとこれらを一気に行うことができます。
> user = User.create(name: "Kanna", email: "kanna@example.com")
(0.1ms) SAVEPOINT active_record_1
User Create (0.4ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "Kanna"], ["email", "kanna@example.com"], ["created_at", "2022-12-26 08:13:30.434879"], ["updated_at", "2022-12-26 08:13:30.434879"]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> #<User id: 1, name: "Kanna", email: "kanna@example.com", created_at: "2022-12-26 08:13:30", updated_at: "2022-12-26 08:13:30">
こちらの方が一手間少ないので楽ですね。
データベースからデータを削除する
データベースからデータを削除したいときはdestroyメソッドを使用します。> user = User.create(name: "Kanna", email: "kanna@example.com")
(0.1ms) SAVEPOINT active_record_1
User Create (0.4ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "Kanna"], ["email", "kanna@example.com"], ["created_at", "2022-12-26 08:13:30.434879"], ["updated_at", "2022-12-26 08:13:30.434879"]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> #<User id: 1, name: "Kanna", email: "kanna@example.com", created_at: "2022-12-26 08:13:30", updated_at: "2022-12-26 08:13:30">
#データベースからデータを削除
>user.destroy
(3.1ms) SAVEPOINT active_record_1
User Destroy (0.4ms) DELETE FROM "users" WHERE "users"."id" = 1 [["id", 1]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> #<User id: 1, name: "Kanna", email: "kanna@example.com", created_at: "2022-12-26 08:13:30", updated_at: "2022-12-26 08:13:30">
しかし、このままだとメモリにデータが残ってしまうので、どうしたものか、、、
データを検索する
・idが1のデータを取り出す。
>> User.find(1)
=> #<User id: 1, name: ",,,,", email: ",,,,,",
created_at: "2019-08-22 01:51:03", updated_at: "2019-08-22 01:51:03">
・属性で検索する
>> User.find_by(email: "katsuki@example.com")
=> #<User id: 1, name: ",,,,,,", email: "katsuki@example.com",
created_at: "2019-08-22 01:51:03", updated_at: "2019-08-22 01:51:03">
・最初のデータを取り出す。
>> User.first
=> #<User id: 1, name: ",,,,,,", email: "katsuki@example.com",
created_at: "2019-08-22 01:51:03", updated_at: "2019-08-22 01:51:03">
・全てのデータを取り出す。
>> User.all
=> #<User id: 1, name: ",,,,,,", email: "katsuki@example.com",
created_at: "2019-08-22 01:51:03", updated_at: "2019-08-22 01:51:03">
データを更新する。
まずはデータを作成します。user = User.create(name: "Katsuki", email: "katsuki@example.com")
(0.1ms) begin transaction
(0.1ms) SAVEPOINT active_record_1
User Create (7.7ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "Katsuki"], ["email", "katsuki@example.com"], ["created_at", "2022-12-27 02:11:37.644016"], ["updated_at", "2022-12-27 02:11:37.644016"]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> #<User id: 1, name: "Katsuki", email: "katsuki@example.com", created_at: "2022-12-27 02:11:37", updated_at: "2022-12-27 02:11:37">
更新する際はupdateメソッドを使用します。
> user.update(name: "Kanna", email: "kanna@example.com")
(0.1ms) SAVEPOINT active_record_1
User Update (0.1ms) UPDATE "users" SET "name" = ?, "email" = ?, "updated_at" = ? WHERE "users"."id" = ? [["name", "Kanna"], ["email", "kanna@example.com"], ["updated_at", "2022-12-27 02:12:06.586763"], ["id", 1]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true
特定の属性のみ更新したい時は、update_attributeメソッドを使います。
> user.update_attribute(:name, "Sanada")
(0.1ms) SAVEPOINT active_record_1
User Update (0.1ms) UPDATE "users" SET "name" = ?, "updated_at" = ? WHERE "users"."id" = ? [["name", "Sanada"], ["updated_at", "2022-12-27 02:12:42.908363"], ["id", 1]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true