Ruby on Rails [学習記録-第3章-]

#モデル
* モデルとは、Railsの中でデータベースへのアクセスをはじめとする情報のやりとりに関する処理を担当しているパート。
* 実体は１つのクラスが定義された◯◯.rbというファイル。
* コントローラでモデルを利用してテーブルからデータを引き出し、ビューファイルに渡すことになる。
* 基本的に、モデルはapp/models以下の階層に設置される。
* モデルを担当するクラスのことをモデルクラスと言う。
![alt](https://www.javadrive.jp/rails/ini/img/p7-1.png)

画像出典：[モデル概念](https://www.javadrive.jp/rails/ini/index7.html)

```rb:sample.rb
class Sample
 def test
 end
end
```
* 対応関係は、テーブルとモデルクラスの名前によって決定する。

###モデルの命名規則
* Railsでは、ファイルやテーブルなどの命名を規則に従った形にする必要がある。
* 命名規則は以下のようになっている。

| 種類                | 概要             | 名前例             |
|:-------------------|:----------------:|:-----------------:|
| モデルクラス名        | 先頭は大文字、単数形 |       App         |
| モデルクラスのファイル名 | 先頭は小文字、単数形 |       app.rb      |
| テーブル名           | 先頭は小文字、複数形 |       apps        |

###モデルファイルの生成コマンド 
* `rails g model`コマンドを使用すると、DBにテーブルを作成するためのファイルとそのテーブルに対応するモデルファイルとを自動で作成される。
* 作成したいモデルのクラス名を全て小文字にしたものを後ろに付けて実行。

```
$ rails g model モデルクラス名(全て小文字) #モデルを作成
```
* モデルファイルを間違えて作成した場合は、`rails d model`コマンドを使用してモデルファイルを削除。

```
$ rails d model モデル名 #作成したモデルを削除
```

#マイグレーションファイル
* マイグレーションファイルは、テーブルの設計図です。マイグレーションファイルにどんなカラムを持つテーブルにするかを書き込み、実行することでテーブルが作成される。
* changeというメソッドで、作成するカラムを指定することができる。
* カラムにはInteger、string、text、boolean、datetimeなどを指定できる。

```rb
class Createテーブル名 < ActiveRecord::Migration[5.2]
  def change
    create_table :テーブル名 do |t|
       t.string      :name
       t.text        :text
       t.text        :image
       t.timestamps null: true
       t.timestamps
    end
  end
end
```
* マイグレーションファイルの実行は以下のコマンドを使用する。

```rb:
$ rake db:migrate
# マイグレーションファイルの実行
```
* マイグレーションファイルは消してはいけない。実行し終わったマイグレーションファイルを削除してしまうと、schema_migrationsと齟齬が生じ問題が生じる恐れがある。

* 読み込んだmigrationファイルの記述が間違っていて、意図しない名前や型を持つテーブルができてしまうことがあります。そのような場合は、rake db:rollback コマンドを利用する。

```
$ rake db:rollback
# データベースの状態を最新のマイグレーションファイルの実行前に戻す
```
#コンソールからレコード情報を読み取る
* rails c とは「rails console」(コンソール)の略です。コンソールを実行すると作成したRailsアプリケーションのメソッドやクラスなどを実際に呼び出すことができる。

```bash:
$ rails c
# コンソールの起動

[1] pry(main)>
```
* コンソールを起動するとpryと表示され、この横にメソッドなどを書いていくことができる。
* 終了するには`exit`と入力する。
* テーブルと、関連するモデルクラスがある現在の状態であれば、コンソール上から実際にコードを書いてテーブルの情報を取得が可能。

```bash:
 pry(main)> app = App.find(1)
＝><Tweet id:1, text:"こんにちは!", created_at:nil, updated_at:nil, name:"ken", image:nil >
 pry(main)> tweet.name
＝>"ken"allメソッド
```
* 上記例では`App`クラスの`find`メソッドを利用しています。
* findメソッドはAppクラスが、ApplicationRecordというクラスを継承しているので使える。

###ActiveRecord
* ActiveRecord(アクティブレコード)はRubyのGemの一種。このGemはモデルとテーブルをつなぎ合わせることで、Railsからテーブルのレコードにアクセスできるようにする
* ActiveRecordはRailsにデフォルトでインストールされている。
* 実際に、この機能を利用する際にはApplicationRecordというクラスを継承して使用する。

###allメソッド
* allメソッドはApplicationRecordを継承したモデルと結びつくテーブルのレコードを全て取得する。

###newメソッド
* newメソッドを実行すると関連するテーブルのカラム名がキーになったハッシュのようなものが生成されます。これをモデルクラスのインスタンスと呼ぶ。インスタンスのそれぞれのキーに値を代入してsaveメソッドを実行するとテーブルに保存される。

```bash:
[1] pry(main)> tweet = Tweet.new(name: "takashi", text: "Nice to meet you!")
[2] pry(main)> tweet.save
```

###createメソッド
*newメソッドとsaveメソッドが行う処理を１度で作成するメソッド。

```bash:
[1] pry(main)> Tweet.create(name: "takashi", text: "Nice to meet you!")
```

###findメソッド
*findメソッドは引数に指定したidにあたる作品情報を1件だけ取得する。該当する値がない場合はエラーになる。

```bash:
pry(main)> tweet = Tweet.find(1)
=><Tweet id:1, text:"こんにちは!", created_at:nil, updated_at:nil, name:"ken", image:nil >
# tweetsテーブルからidが1のレコードを取得し、tweetという変数に代入
```

###saveメソッド
*上書きを保存するにはインスタンスのsaveメソッドを行う。

```bash:
user = User.find(1)    # Usersテーブルのidが1のレコードを取得
puts user.name
=> "Shinbo"            # nameカラムの値は"Shinbo"
user.name = "Abe"  # nameカラムの値を"Abe"に上書き
user.save              # 変更をデータベースに反映
puts user.name         
=> "Abe"               # nameカラムの値が"Abe"に更新された
```