Day6です!
今日もがんばっていきましょー!
読んでいただいている方、いつもありがとうございます!
初心者なもので、たまに間違った内容もあるかと思います。
その際にはコメントやTwitterでご指摘いただけると幸いです!
[Da6]第六章6.1〜6.4作業ログ
いつものお決まりトピックブランチの作成
git checkout -b modeling-users
Modelの作成
今回の主題は、データベースを作ること。
まずはモデルを作ってデータが保存できるようにします。
まずはUserモデルを作ってあげて、
rails g model User name:string email:string
こうすると、migrationファイルが~/db/migrateにできます。
その後に、rails db:migrate
でデータベースに変更が保存されます。
そういえば、migrationはrails db:rollback
で戻せましたね。
Day3でもまとめました。
参考:[Day3 Rails Tutorial]第三章完|herokuにデプロイできない問題にうまく対処![3.1.〜3.5]
データベースを実験的にいじる
rails console --sandbox
とこのようにオプションを付けてあげると、コンソール終了時にすべての変更をロールバック(取り消し)してくれるサンドボックスモードでコンソールが起動。
Any modifications you make will be rolled back on exit
わかりやすく、こう明記してくれています。
データベースのコマンドあれこれ
作成&削除
コンソール起動後、
user = User.new(name: "ex", email: "ex@mail.com" )
でインスタンスが作れる。そして、
user.save
で保存。
実は作成と保存は同時にできて、コマンドは以下。
user = User.create(name: "ex", email: "ex@mail.com" )
またuser.destroy
で消せる。
検索
User.find(n)
:idがnのuserを探す。
User.find_by(email: "ex@mail.com")
:emailがex@mail.comのuserを探す。
上のemailのところを変えれば、いろんな条件で検索可能。
User.first
:idが1のuserを探す。
User.all
:すべてのuserを探す。
更新
user
:現状確認
user.name = "abc"
:name変更
user.save
:保存
また保存する前に、user.reload
とうつと、データベースから読み込み直すので、変更前のエータが表示される。
user.update_attributes(name: "ex", email: "ex@mail.com")
でも変更できる。注意したいのが、この場合は変更・保存を同時に行うこと。
バリデーションの設定
Userモデルに対してバリデーションの設定。
class User < ApplicationRecord
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
end
存在と文字数制限はおなじみ。
注目すべきは3点。コードの下の方から説明していきます。
1つ目はemailの正規表現によるバリデーション。
これでメールアドレスの形をした文字列しか登録できなくなった。
Webアプリっぽくなってきましたねー!
正規表現についてはチュートリアルでもおすすめされていた、『Rubular』が面白かったです。
2つ目は、emailの一意性にも注目。
uniqueness: true
でも普通は悪くない。
でもメールアドレスは通常大文字小文字を無視するから、センシティブなケースとして、このように書く。
uniqueness: { case_sensitive: false }
こうすることで、ABC@mail.comとabc@mail.comは同じアドレス扱いではじかれる。
最後に3つ目、DBに保存する前にアドレスを小文字に変換すること。
いくつかのデータベースのアダプタが、常に大文字小文字を区別するインデックス を使っているとは限らない問題への対処
コールバック関数のbefore_save
というコマンドを使って、保存される前にアドレスを小文字に変換しています。
before_save { self.email = email.downcase }
has_secure_passwordメソッドで安全なパスワードを導入
railsには便利なメソッドがあって、has_secure_passwordメソッドを使うだけで、セキュアなパスワードが導入できるらいいです。
導入の仕方はたった2STEP。
- app/models/user.rbに
has_secure_password
を追加 - bcrypt gemをインストール
class User < ApplicationRecord
...
has_secure_password
end
Gemfileにgem 'bcrypt', '3.1.12'
追加してbundle install
するだけ。
導入すると、パスワードのカラム名が自動的にpassword_digestに変わる。ここにはパスワードがハッシュ化された値が入る。
認証は、authenticateメソッドで行う。
authenticateメソッドは、引数をハッシュ化した値とauthenticateメソッドの値が同じか調べてくれる。
違っていればfalseを返し、合っていればユーザーオブジェクトを返す。
ログイン認証で使うから、大事な内容。
さいごはいつも通りcommitとpush|herokuには注意
さいごはいつも通り、commitとpushしておきました。
ただ一点だけ注意。
herokuの本番環境でUserモデルを使うためには、heroku run
コマンドを使ってHeroku上でもマイグレーションを走らせる必要があるそう。
これを実行すればOK。
heroku run rails db:migrate
今日もおつかれでしたー!
タケシなりの演習の回答
created_atとupdated_atは、どのクラスのインスタンスでしょうか?
>> user.created_at.class
=> ActiveSupport::TimeWithZone
コンソールを一度再起動して (userオブジェクトを消去して)、このセクションで作ったuserオブジェクトを検索してみてください。
オブジェクトが検索できたら、名前を新しい文字列に置き換え、saveメソッドで更新してみてください。うまくいきませんね…、なぜうまくいかなかったのでしょうか?
たしかに更新できなかった!エラーメッセージはこうだった。
>> user.errors.messages
=> {:password=>["can't be blank", "is too short (minimum is 6 characters)"]}
今度は6.1.5で紹介したテクニックを使って、userの名前を更新してみてください。
6.1.5で紹介したテクニックとは、update_attribute(sは付かないことに注意)を使うことですね。
ただし、検証に1つでも失敗すると、 update_attributesの呼び出しは失敗します。(中略)特定の属性のみを更新したい場合は、次のようにupdate_attributeを使います。このupdate_attributeには、検証を回避するといった効果もあります。
>> user.update_attribute(:name, "El Duderino")
(0.1ms) begin transaction
SQL (2.4ms) UPDATE "users" SET "name" = ?, "updated_at" = ? WHERE "users"."id" = ? [["name", "El Duderino"], ["updated_at", "2018-09-06 03:05:12.920773"], ["id", 1]]
(6.4ms) commit transaction
=> true
user.save
しなくてもデータを更新してくれます。(user.save
するとfalseって出ます)
ちなみにキーの書き方ですが、こっちではエラーが出ました。
>> user.update_attribute(name: "El Duderino") ArgumentError: wrong number of arguments (given 1, expected 2) from (irb):3
[Day6]まとめ
- 学習範囲:6.1〜6.4
- 学習時間:3時間10分
- 総学習時間:27時間
- 反省点:今日はわりとスムーズにすすんだ!あと不明な点についてちゃんと調べることができた。特にherokuあたりはGOOD!
これまでチュートリアルを進めてきて感じたことですが、気になるところ、疑問に思ったところはその都度調べるのがいい!
あとあとチュートリアルでけっこう出てくる!その時の感動がすごい!
また、一度見てる情報だから理解が早い。
あと自分で調べる力をつけるのはものすごく大事ですからね。
読んでいただいている方、いつもありがとうございます!
初心者なもので、たまに間違った内容もあるかと思います。
その際にはコメントやTwitterでご指摘いただけると幸いです!
コメントを残す