rails tutorial6章進めた時の覚書

##この章では何するの？
6章ではユーザー登録機能の中でも、一番重要なステップであるユーザー用のデータモデルの作成と、データを保存する手段の確保について学びます。

6~12章でRailsのログインと認証システムをひととおり開発します。

ユーザー登録で初めにやることは、それらの情報を保存するためのデータ構造を作成すること

データベースとやりとりをするデフォルトのRailsライブラリはActive Recordと呼ばれる

Railsには***マイグレーション（Migration）***という機能がある。
データの定義をRubyで記述することができ、SQLのDDL（Data Definition Language）を新たに学ぶ必要がない。
このマイグレーションはDjangoと同じだよな？？
データをデータベースに登録する作業という認識であっているかね。

name, email 属性をつけたUserモデルを作るコマンド

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

String型のname属性、String型のemail属性を持つUserモデルを制作している

***コントローラ名には複数形***を使い、***モデル名には単数形***を用いるという慣習を頭に入れる。
コントローラは`Users`
モデルは`User`

`rails genarate`コマンドの結果の一つとして、マイグレーションファイルが生成される
マイグレーションは、データベースの構造をインクリメンタルに変更する手段を提供し、要求が変更された場合にデータモデルを適合させることができる

マイグレーション自体は、データベースに与える変更を定義したchangeメソッドの集まり。

changeメソッドはcreate_tableというRailsのメソッドを呼び、ユーザーを保存するためのテーブルをデータベースに作成

`t.timestamps`は、特別なコマンドで、created_atとupdated_atという２つの「マジックカラム（Magic Columns）」を作成する。

マイグレーションの実行

```
$ rails db:migrate
```

migrateコマンド叩くと、`db/development.sqlite3`ファイルが生成される
これはSQLiteの実体

マイグレーションを戻すことを `ロールバック`と呼ぶ。Railsでは、下記叩く

```
$ rails db:rollback
```

コンソールをサンドボックで起動する。
そのセッションで行ったデータベースへの変更をコンソールの終了時全てロールバックしてくれる

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

User.newを引数なしで呼んだ場合は、すべての属性がnilのオブジェクトを返す

データベースにUserオブジェクトを保存するためには、userオブジェクトからsaveメソッドを呼び出す必要がある

```
#ユーザーオブジェクトの生成(全てnilで設定される)
>> User.new

#ユーザーオブジェクトの値を設定
>> user = User.new(name: "Michael Hartl", email: "michael@example.com")

#データベースにUserオブジェクトを保存
>> user.save

#モデルの生成と保存を同時に行う
>> User.create(name: "Gerge", email: "krooby@example.com")

#user.createはユーザーオブジェクト自身を返す。変数に代入もできる
>> foo = User.create(name: "Foo", email: "foo@example.com")
```

##ユーザーオブジェクトの検索
```
>> User.fidn(1)
```

特定の属性でユーザー検索

```
>> User.find_by(email: "michael@example.com")
```

```
#データベースの最初のユーザーを返す
>> User.first

#データベースのすべてのUserオブジェクトを返す
>> User.all
```

##ユーザーオブジェクトの更新
更新後、saveを実行する。

```
>> user.email = "changemail@example.com"
>> user.save
```

これは、何番目のユーザーのemailを変更しているんだ？

```
>> user.email
```

更新方法もう一つ
`update`を使う。

```
>> user.update(name: "seno shu", email: "seno@example.com")
```

例えば下記を叩いたときに、idが幾つのユーザーとか指定していないが、更新されるのは最初のユーザーの情報という認識であっているのかな？

```
>> user.email = "foo@bar.com"
```

あーなるほど。更新する際に、 `user.email` をしてしたら、userに代入していたユーザーの情報が更新されるんだ。つまりそもそも下記の認識がそもそも間違えていて、 `user` に代入している値としっかり指定しているじゃないか。

> idが幾つのユーザーとか指定していないが

特定の属性のみ更新したい場合は、

`update_attribute`を利用する。

```
>> user.update_attribute(:name, "Upload Name")
=> true
>> user.name
=> "Upload Name"
```

`assert`メソッド
テスト用のメソッド。第一引数がtrueであることを期待する。
第二引数は期待が裏切られてたときに出力するメッセージ
例えばemailをテストする時に下記のように記述する
もし、userがvalidじゃないときに、どのメールアドレスでテストが失敗したのかを特定できる。

```rb:user_test.rb
assert @user.valid?, "#{valid_address.inspect} should be valid"
```


##セキュアなパスワードの追加
パスワードをハッシュ化する。
Rubyのデータ構造であるハッシュとは別の話で、今回の「ハッシュ化」は構造の事ではなく、ハッシュ関数を使って、入力されたデータを***元に戻せない（不可逆な）データにする処理***を指す。

セキュアなパスワードの実装は、モデルに`has_secure_password`メソッドを利用することで殆ど可能。

> - セキュアにハッシュ化したパスワードを、データベース内のpassword_digestという属性に保存できるようになる。
- 2つのペアの仮想的な属性（passwordとpassword_confirmation）が使えるようになる。また、存在性と値が一致するかどうかのバリデーションも追加される19 。
- authenticateメソッドが使えるようになる（引数の文字列がパスワードと一致するとUserオブジェクトを、間違っているとfalseを返すメソッド）。

`has_secure_password`メソッドを使うためにはモデル内に`password_digest`属性を持っている必要がある。

本番環境でUserモデルを使うためには、`heroku run`コマンドを使ってHeroku上でもマイグレーションを走らせる必要がある。