rails_tutorial chapter6 <忘備録>


・ユーザーモデルの作成

モデルを作成

rails g model User name:string email:string

バリデーションの記述

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

emailにindexを追加
indeを追加することにより、データベースからデータの取り出しを効率的に行う。

rails generate migration add_index_to_users_email
class AddIndexToUsersEmail < ActiveRecord::Migration[6.0]
  def change
    add_index :users, :email, unique: true
  end
end

データベースをマイグレート

rails db:migrate

has_secure_passwordを追記

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 }
  has_secure_password
  validates :password, presence: true, length: { minimum: 6 }
end

上のようにモデルにこのメソッドを追加すると、次の機能が使えるようになる。
ただし、1つだけ条件があります。それは、モデル内にpassword_digestという属性が含まれていることです。

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

has_secure_passwordが使えるように、モデルにpassword_digestカラムを追加

rails generate migration add_password_digest_to_users password_digest:string
class AddPasswordDigestToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :password_digest, :string
  end
end

データベースをマイグレート

rails db:migrate

has_secure_passwordを使ってパスワードをハッシュ化するためには、ハッシュ関数であるbcryptが必要になるので、gemを追加。

source 'https://rubygems.org'
gem 'rails',          '6.0.4'
gem 'bcrypt',         '3.1.13'
gem 'bootstrap-sass', '3.4.1'
・
・
・

そして、いつものように

bundle install

まとめると、has_secure_passwordを使用するためには、
1、password_digestカラムの追加
2、bcrypt gemの追加

その後、User.createすると、password_digestにはbcryptを通して、ハッシュ化した値を自動で保存してくれる。
仮想的なpasswordとpassword_confirmationを用意してくれるのは楽ですね。

また、authenticateメソッドの引数にパスワードを入力して正しければユーザーの情報が返り、異なっていればfalseが返ってくる。

irb(main):009:0> user.authenticate('foobar')
=> #<User id: 1, name: "Michael Hartl", email: "[email protected]", created_at: "2022-03-23 04:32:06.612164000 +0000", updated_at: "2022-03-23 04:32:06.612164000 +0000", password_digest: [FILTERED]>

irb(main):010:0> user.authenticate('foobr')
=> false

以上、6章の重要部分のまとめでした。
ログインにはdeviseなど他のgemを使うことができますが、元々の動きを知らなければ使うのに支障が出そうなので、車輪の再発明ではありますが、いい章でした。