[Day6 Rails Tutorial]第六章完|データベースとログイン認証の勉強[6.1〜6.4]

Rails Tutorial day1 感想 まとめ 振り返り エラー解決 演習問題 回答

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モデルに対してバリデーションの設定。

user.rb
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』が面白かったです。

rails tutorial 正規表現 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。

  1. app/models/user.rbにhas_secure_passwordを追加
  2. bcrypt gemをインストール
user.rb
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でご指摘いただけると幸いです!

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です