メモランダム Rails tutorial　第6章

# Rails tutorial 第６章

# ユーザーのモデルを作成する
- 認証 (authentication) と認可 (authorization) のシステムの例だと、Clearance、Authlogic、Devise、CanCanなど

# 1. Userモデル
- 情報を保存するためのデータ構造を作成する
- Railsでは、データモデルとして扱うデフォルトのデータ構造のことをモデル (Model) と呼びます 
- データベースとやりとりをするデフォルトのRailsライブラリはActive Recordと呼ばれます

### データベースの移行
- この節での目的は、簡単に消えることのないユーザーのモデルを構築すること
- nameとemailの2つの属性からなるユーザーをモデリングするところから始める
 - `attr_accessor :name, :email`は必要ない
 - generate modelというコマンドを使います
 -`$ rails generate model User name:string email:string`

### modelファイル
- この節では、以後このモデル用ファイルを理解することに専念します
 
### ユーザーオブジェクトを作成する。
- Active Recordを理解する上で、「有効性 (Validity)」という概念も重要
 - データベースにデータがあるかどうかは有効性には関係ありません
- Userモデルのインスタンスはドット記法を用いてその属性にアクセスすることができます
- create, destroy

### ユーザーオブジェクトを検索する
- `User.find(3)`
- `User.find_by(email: "mhartl@example.com")`
- `User.first`
- `User.all`

### ユーザーオブジェクトを更新する。
- 基本的な更新の方法は2つ
 - 属性を個別に代入する方法
 - update_attributesを使うケース 
  - `user.update_attribute(:name, "El Duderino")`


# 2.ユーザーを検証する。

- nameとemailにあらゆる文字列を許すのは避けるべき
 - 存在性 (presence)の検証、
 - 長さ (length)の検証、
 - フォーマット (format)の検証、
 - 一意性 (uniqueness)の検証
 
### 有効性を検証する。
- 有効なUserかどうかをテストする
 - `assert @user.valid?`
 - `$ rails test:models`
 -
 
### 存在性を検証する
- 「存在性 (Presence)」。これは単に、渡された属性が存在することを検証する。
 - name属性にバリデーションに対するテスト
  - `assert_not @user.valid?`
 - name属性の存在性を検証する
  - ` validates :name, presence: true`
  - `validates(:name, presence: true)`
  - ` user.errors.full_messages`


### 長さを検証する
- nameの長さの検証に対するテスト
 - `user.name = "a" * 51`
- `validates :name,  presence: true, length: { maximum: 50 }`
- `validates :email, presence: true, length: { maximum: 255 }`


### フォーマットを検証する
- ここではメールアドレスにおなじみのパターンuser@example.comに合っているかどうかも確認することを要求します
　- %w[]という便利なテクニック
　- `assert @user.valid?, "#{valid_address.inspect} should be valid"`

- このオプションは引数に正規表現 (Regular Expression) (regexとも呼ばれます) を取ります。正規表現は一見謎めいて見えますが、文字列のパターンマッチングにおいては非常に強力な言語です。つまり、有効なメールアドレスだけにマッチして、無効なメールアドレスにはマッチしない正規表現を組み立てる必要があります
 - `VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i`
 - `  format: { with: VALID_EMAIL_REGEX }`

### 一意性を検証する
- validatesメソッドの:uniqueオプションを使います
- `  test "email addresses should be unique" do
    duplicate_user = @user.dup
    @user.save
    assert_not duplicate_user.valid?
  end`
 - @userと同じメールアドレスのユーザーは作成できないことを、@user.dupを使ってテストしています
- emailのバリデーションにuniqueness: trueというオプションを追加


# 3.セキュアなパスワードを追加する
- 、ハッシュ関数を使って、入力されたデータを元に戻せない (不可逆な) データにして保存する。

### ハッシュ化されたパスワード
- セキュアなパスワードの実装は、has_secure_passwordというRailsのメソッドを呼び出すだけでほとんど終わってしまいます
- 今回の用途ではハッシュ化されたパスワードと暗号化されたパスワードは類義語となります
- has_secure_passwordを使ってパスワードをハッシュ化するためには、最先端のハッシュ関数であるbcryptが必要になります。パスワードを適切にハッシュ化することで、たとえ攻撃者によってデータベースからパスワードが漏れてしまった場合でも、Webサイトにログインされないようにできます。サンプルアプリケーションでbcryptを使うために、bcrypt gemをGemfileに追加します

### パスワードの最小文字数
- `test "password should be present (nonblank)" do
    @user.password = @user.password_confirmation = " " * 6
    assert_not @user.valid?
  end`

- ` test "password should have a minimum length" do
    @user.password = @user.password_confirmation = "a" * 5
    assert_not @user.valid?
  end`

- `validates :password, length: { minimum: 6 }`
- `validates :password, presence: true, length: { minimum: 6 }`


### ユーザーの作成と認証
- has_secure_passwordをUserモデルに追加したことで、そのオブジェクト内でauthenticateメソッドが使えるようになっています


# 4.最後に
- たった12行でここまでの機能が実装できたことは、Railsの注目に値する特長でもあります

### 本章のまとめ
- マイグレーションを使うことで、アプリケーションのデータモデルを修正することができる
- Active Recordを使うと、データモデルを作成したり操作したりするための多数のメソッドが使えるようになる
- Active Recordのバリデーションを使うと、モデルに対して制限を追加することができる
- よくあるバリデーションには、存在性・長さ・フォーマットなどがある
- 正規表現は謎めいて見えるが非常に強力である
- データベースにインデックスを追加することで検索効率が向上する。また、データベースレベルでの一意性を保証するためにも使われる
- has_secure_passwordメソッドを使うことで、モデルに対してセキュアなパスワードを追加することができる