railsチュートリアル　第六章

##はじめに
railsチュートリアルで理解しにくいところや、詰まったところを書いていく記事になります。
なので、手順を示す記事とはなっていません。

##データベースの構造の確認

Userモデルを生成し、db:migrateコマンドを打つと**db/development.sqlite3**という名前のファイルが生成される。↓

```
$ rails generate model User name:string email:string
$ rails db:migrate
```

通常は**DB Browser for SQLite**というツールを利用しデータベースの構造の確認ができるが、今回僕はcloud9(クラウドIDE)を使っているので、ファイルをダウンロードし、Spliceというアプリを使ってデータベースの構造を確認することができた。

便利！！

##サンドボックス

```
$ rails console --sandbox
```

↑のようなコマンドを打つと、コンソールをサンドボックスで起動することができる。

起動すると以下のようなメッセージがでる。
```Any modifications you make will be rolled back on exit```

**ここで行ったすべての変更は終了時にロールバックされます**

ということで、データベースを変更せずにコンソールを使いたい場合はサンドボックスモードにするといい。

##ユーザーオブジェクトを更新

いったん作成したオブジェクトを更新したい場合は```update_attributesメソッド```を使うといい。

例：

```
user.update_attributes(name: "The Dude", email: "dude@abides.org")
```

**update_attributesメソッド**は属性のハッシュを受け取り、**成功時には更新と保存を続けて同時に行う。**
保存に成功すれば、trueを返してくれる。

##バリデーションとテスト駆動開発

バリデーションとテスト駆動開発は相性が良く、まず失敗するテストを書き、次にテストを成功させるように実装すると、期待した通りに動いているかを確認することができる。

例：

 ```test/models/user_test.rb
require 'test_helper'

class UserTest < ActiveSupport::TestCase

  def setup
    @user = User.new(name: "Example User", email: "user@example.com")
  end

  test "should be valid" do
    assert @user.valid?
  end

  test "name should be present" do
    @user.name = "     "
    assert_not @user.valid?
  end
end
```
**setupメソッド**で@userを定義しておく。
setupメソッドの中の書かれた処理は各テストが走る直前に実行される。

@user.nameを空白にし、**assert_notメソッド**を使うことで有効性を確認できる。

まだ、validatesをかけていなければテストはREDになる。

以下のようにすることで、テストはGREENとなる。

```app/models/user.rb
validates :name,  presence: true
```

##メールの正規表現

email属性の場合は、有効なメールアドレスかどうかを判定するために、もっと厳重な要求を満たさなければらない。
空のアドレスに対してvalidatesするだけではなく、
user@example.com
にフォーマットが合っているかを確認する必要がある。
以下にそのテストを載せる。

例：
有効なメールアドレス

```test/models/user_test.rb
test "email validation should accept valid addresses" do
    valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org
                         first.last@foo.jp alice+bob@baz.cn]
    valid_addresses.each do |valid_address|
      @user.email = valid_address
      assert @user.valid?, "#{valid_address.inspect} should be valid"
    end
end
```
無効なメールアドレス(,があったり、@がない)

```test/models/user_test.rb
test "email validation should reject invalid addresses" do
    invalid_addresses = %w[user@example,com user_at_foo.org user.name@example.
                           foo@bar_baz.com foo@bar+baz.com]
    invalid_addresses.each do |invalid_address|
      @user.email = invalid_address
      assert_not @user.valid?, "#{invalid_address.inspect} should be invalid"
    end
end
```

```assert @user.valid?, "#{valid_address.inspect} should be valid"```
により、どのメールアドレスでテストが失敗したかわかるようにする。

このテストをGREENにするなら以下のようなvalidatesが必要になる。

```app/models/user.rb
class User < ApplicationRecord
  #空白と長さに対するvalidatesを含む
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX }
end
```

他にも一意性を持たせないといけないが割愛。

##セキュアなパスワード

セキュアパスワードという手法では、各ユーザーにパスワードとパスワードの確認を入力させ、それを (そのままではなく) ハッシュ化したものをデータベースに保存する。

ユーザーの認証は、パスワードの送信、ハッシュ化、データベース内のハッシュ化された値との比較、という手順で進む。

**比較するのは生のパスワードではなく、ハッシュ化されたもの同士である。**

そのために```has_secure_password```というメソッドを利用する。

このメソッドはUSERモデル内で呼びだすことができる。

```
class User < ApplicationRecord
  .
  .
  .
  has_secure_password
end
```

モデルにこのメソッドを追加することで、

>・データベース内のpassword_digestというカラムにハッシュ化したパスワードを保存
・passwordとpassword_confirmationの利用
・authenticateメソッドが使用

が可能になる。

このメソッドを使用するにはデータベースに```password_digest```というカラムを追加する必要がある。
(マイグレーションファイルを作り、changeメソッド内に処理を書き、マイグレートする)

また、**bcryp**tをインストールしていない場合は、```Gemfile```に記述し、```bundle install```を実行しておく。

###authenticateメソッド

ハッシュ化されたもの同士を比較するには```authenticateメソッド```を利用する。
引数の文字列がパスワードと一致すれば、**Userオブジェクト**を、間違っていれば**false**を返す。

```
>>user.authenticate("not_the_right_password")
false
>> user.authenticate("right_password")
ユーザーオブジェクトが返される
```
##おわり

第六章は、メインはユーザー登録に対するバリデーションとそれに対するテストだった。
ここも必須の行程になるだろうな。

次↓
https://qiita.com/jonnyjonnyj1397/items/b1fb517fd922934cdd3e