##この章では何するの?
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という2つの「マジックカラム(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じゃないときに、どのメールアドレスでテストが失敗したのかを特定できる。
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上でもマイグレーションを走らせる必要がある。