Railsチュートリアル（第6章）

# はじめに
Railsチュートリアルの第6章が終わりました。
ポイントだけメモしておきます。

# モデル
モデルを作成する際は、`rails generate`コマンドで作成します。モデル名は単数形にするということに気をつけます。

```
rails generate model "モデル名" "カラム名":"型"
```
例えば、string型の`name`と`email`を持つ`User`モデルを作成する際は、以下のようなコマンドを実行します。

```
rails generate model User name:string email:string
```
このコマンドを実行すると、以下のようなファイルが作成されます。
（ファイル名の[timestamp]の部分はコマンドを実行した日時）

```rb:db/migrate/[timestamp]_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email

      t.timestamps
    end
  end
end
```

`t.timestamps`の部分は自動で作成され、作成日時を表す`created_at`と更新日時を表す`updated_at`というカラムを自動で設定してくれます。

# モデルの追加
モデルに新しくデータを追加する際は、以下のように、`new`した後に、`save`を実行します。

```rb
user = User.new(name: "Test", email: "sample@example.com")
user.save
```
また、上記の`new`と`save`をまとめたものが、以下の`create`です。

```rb
User.create(name: "Test", email: "sample@example.com")
```

# モデルの検索
モデルの中から特定のidのデータを取得する際は、`find("id")`で取得できます。

```rb
User.find(1)
```
idではなく、任意のカラムで検索したい場合は、`find_by("ハッシュ")`で取得できます。

```rb
User.find_by(email: "sample@example.com")
```
他にも、最初のデータを取得する`first`や、全てのデータを取得する`all`などがあります。

```rb
User.first
User.all
```

# モデルの更新
モデルのデータを更新する際は、検索等で取得した1件分のデータ`user`に対して、カラムの内容を書き換えた後に、`Save`を実行します。

```rb
user.name = "Test2"
user.save
```
また、`update_attributes("ハッシュ")`の形式でも更新できます。

```rb
user.update_attributes(name: "Test2", email: "sample2@example.com")
```
更新するカラムが1つの場合は、`update_attribute`と単数にできます。
この際は、validateのチェックが走らないようです。

```rb
user.update_attribute(name: "Test2")
```

# モデルのテスト
モデルのテストは、`test/models`配下の`"モデル名"_test.rb`に記述します。
以下のような`setup`メソッドを記述することで、各テストが実行される前に、この`setup`メソッドが呼ばれます。ここで、インスタンス変数にテストデータを格納することで、各テストでテストデータを使うことができるようになります。

```rb:test/models/user_test.rb
def setup
  @user = User.new(name: "Test", email: "sample@example.com")
end
```

## 有効性
モデルの有効性をテストする際は、`valid?`メソッドを使います。

```rb
  assert @user.valid?
```

## 存在性
カラムに値が入っているかをテストする際は、まず以下のように、「データが空白の場合は有効でない」ということを確認するテストを書きます。

```rb
  @user.name = "     "
  assert_not @user.valid?
```
次に、モデルのファイルに、validateを追加します。
必須入力チェックである`presence`をtrueにしておきます。

```rb:app/models/user.rb
class User < ApplicationRecord
  validates :name, presence: true
end
```

## 長さ
長さのテストをする際は、実際に長い文字列を入力して、有効でないことを確認します。
文字列に数字をかけると、その文字列を数字分繰り返します。

```rb
  @user.name = "a" * 51
  assert_not @user.valid?
```
次に、モデルのファイルに、長さのvalidateを追加します。
`maximum`で最大値、`minimum`で最小値を設定できます。

```rb:app/models/user.rb
  validates :name,  presence: true, length: { maximum: 50 }
  validates :email, presence: true, length: { maximum: 255 }
```

## フォーマット
フォーマットをテストする際は、モデルのファイルに、フrb:app/models/user.rbォーマットのvalidateを追加します。
withの後は、正規表現で記述します。

```rb:app/models/user.rb
  validates :email, format: { with: /<regular expression>/ }
```

## 一意性
とあるカラムが同じデータが存在していないかテストする場合は、validateにて`uniqueness`をtrueにして、一意性をチェックします。

```rb:app/models/user.rb
  validates :email, uniqueness: true
```
また、以下のように、trueの部分に、`{ case_sensitive: false }`と記述することで、`uniqueness`をtrueにしつつ、大文字小文字を区別しないようにできます。

```rb:app/models/user.rb
uniqueness: { case_sensitive: false }
```

# パスワード
モデルにパスワードを含む際、よりセキュアなものにするために、モデルに`has_secure_password`の記述を追加します。
これにより、パスワードを保存する際に、ハッシュ化してデータベースに保存したり、`password`と`password_confirmation`という確認用のカラムが自動的に使用できるようになります。
ただし、このメソッドを使用するためには、あらかじめモデルに、`password_digest`というカラムを追加しておく必要があります。

```rb:app/models/user.rb
class User < ApplicationRecord
  has_secure_password
end
```
## カラムの追加用マイグレーション
すでに作成しているテーブルにカラムを追加するためのマイグレーションファイルは以下のコマンドを実行して作成します。
以下の例は、`users`テーブルに`password_digest`を追加しています。
マイグレーションファイル名の末尾に、`_to_"テーブル名"`とつけることで、自動でそのテーブルへの追加用マイグレーションファイルを作成してくれます。
カラムの指定はモデルを作成した際と同じです。

```
rails generate migration add_password_digest_to_users password_digest:string
```