Rails データベース作成　モデルの基本操作

<h1>この記事でわかること</h1>
<h6>
<ol>
<ul>・Railsモデルの基本操作について。</ul>
</ol>
</h6>



<h1>モデルを作成する</h1>
まずは、モデルを以下のコマンドで作成します。

```Bash:console
rails generate model <model-name> <データ名:データ型> <データ名:データ型> 
rails generate model User name:string email:string
```

すると以下のようなコードが表示されます。

```Bash:console
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
```
<h1>マイグレーション</h1>
モデルをrails generateコマンドで作成するとマイグレーションファイルが作成されます。

```Ruby:sample_app/db/migrate/20221226012605_create_users.rb
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メソッドが定義されています。このマイグレーションというのは、データベースの変更を定義するもので、マイグレーションを実行することで、データベースに変更を加えることができます。<br>

このファイルが生成されている時点では、マイグレーションは実行されていません。<br>

ちなみに、このファイルにはusersにデータとしてstring型のname属性とemail属性を追加、さらにタイムスタンプを追加することが記述されています。

このファイルを確認したら早速マイグレーションを以下のコードで実行します。

```Bash
rails db:migrate
```

これにより、development.sqliteというファイルが作成されます。
このファイルを確認すると、データベースが作成されています。(VSCodeだとファイルの中身を見ることができないので、 [DB Browser for SQlite](https://sqlitebrowser.org/)というWebアプリを使用して中身を確認します。↓↓)

![スクリーンショット 2022-12-26 12.20.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2708737/8dbfe611-9d9c-578f-f00f-91cd7bb76781.png)

これで、実際にデータベースを操作していく準備が整いました。

<h1>基本操作(作成、更新、削除)</h1>
<h2>ユーザーオブジェクトを作成する</h2>
Railsでは基本的なデータベースの操作をRailsのメソッドを使用することで行うことができます。例えば、新しいデータを作成したいときは以下のようにコマンドを打ちます。ここでは、rails consoleを使用することにします。
<br>
<br>
オプションで--sandboxをつけることで、行った変更などが実際には反映されずに、コンソールを閉じた瞬間に削除されます。


```Bash:console
$rails console --sandbox
```

以下のコマンドではUserオブジェクトを作成しています。Userオブジェクトには四つの属性がありますが、それぞれには何も入れていませんので、返り値はnilになっています。
```Ruby:rails console
>> User.new
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil>
```

また、以下のコードのように属性に値を代入することもできます。
```Ruby:rails console
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>
```

<h3>オブジェクトの有効性を確かめる</h3>
ここまででUserオブジェクトを作成し、それをuserに代入しています。このUserオブジェクトが有効性があるかどうかを確かめるコードがいかになります。

```Ruby:rails console
#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は以下のようになっています。
```Ruby:app/models/user.rb
class User < ApplicationRecord
end
```
ここには有効性に関する定義がまだされていないので、先ほどのコードではuser,user2に格納されているデータの有無や数に関わらずvalid?メソッドはtrueを返り値として返します。

例えば、user.rbに以下のようにコードを追加したとします。
```Ruby:app/models/user.rb
class User < ApplicationRecord
    validates :name, presence: true
end
```
validatesはrailsのメソッドで、どんなデータを有効とするかに関する定義を行うことができます。ここでは、:nameというデータについての定義を行っています。presence:は「空ではない」という意味で、引数にtrueが書いてあるので、この場合は「:nameというデータが空ではないとき、そのデータは有効である。」という意味になります。

このように定義すると、先ほどのコードに対するvalid?メソッドの返り値が以下のように変わります。

```Ruby:rails console
#:nameが空でないオブジェクト
>user.valid?
=>true

#:nameが空のオブジェクト
>user2.valid?
=>false
```
有効性に関する知識はテストの際にとても重要になるのでここで押さえておきましょう。

<h2>データベースにデータを保存する。</h2>
今まで、User.newでデータを作成してきましたが、これだけだとまだデータベースにデータを保存できていません。なので、データをしっかりと保存しておきましょう。

```Ruby:rails console
#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メソッドを使うとこれらを一気に行うことができます。

```Ruby:rails console
> 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">
```
こちらの方が一手間少ないので楽ですね。

<h2>データベースからデータを削除する</h2>
データベースからデータを削除したいときはdestroyメソッドを使用します。

```Ruby:rails console
> 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">
```
しかし、このままだとメモリにデータが残ってしまうので、どうしたものか、、、

<h2>データを検索する</h2>
<h3>・idが1のデータを取り出す。</h3>

```Ruby:rails console
>> User.find(1)
=> #<User id: 1, name: ",,,,", email: ",,,,,",
created_at: "2019-08-22 01:51:03", updated_at: "2019-08-22 01:51:03">
```
<h3>・属性で検索する</h3>

```Ruby:rails console
>> 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">
```
<h3>・最初のデータを取り出す。</h3>

```Ruby:rails console
>> 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">
```

<h3>・全てのデータを取り出す。</h3>

```Ruby:rails console
>> 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">
```

<h2>データを更新する。</h2>
まずはデータを作成します。

```Ruby:rails console
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メソッドを使用します。

```Ruby:rails console
> 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メソッドを使います。

```Ruby:rails console
> 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
```