railsチュートリアル 第六章


はじめに

railsチュートリアルで理解しにくいところや、詰まったところを書いていく記事になります。
なので、手順を示す記事とはなっていません。

データベースの構造の確認

Userモデルを生成し、db:migrateコマンドを打つとdb/development.sqlite3という名前のファイルが生成される。↓

$ rails generate model User name:string email:string
$ rails db:migrate

通常はDB Browser for SQLiteというツールを利用しデータベースの構造の確認ができるが、今回僕はcloud9(クラウドIDE)を使っているので、ファイルをダウンロードし、Spliceというアプリを使ってデータベースの構造を確認することができた。

便利!!

サンドボックス

$ rails console --sandbox

↑のようなコマンドを打つと、コンソールをサンドボックスで起動することができる。

起動すると以下のようなメッセージがでる。
Any modifications you make will be rolled back on exit

ここで行ったすべての変更は終了時にロールバックされます

ということで、データベースを変更せずにコンソールを使いたい場合はサンドボックスモードにするといい。

ユーザーオブジェクトを更新

いったん作成したオブジェクトを更新したい場合はupdate_attributesメソッドを使うといい。

例:

user.update_attributes(name: "The Dude", email: "[email protected]")

update_attributesメソッドは属性のハッシュを受け取り、成功時には更新と保存を続けて同時に行う。
保存に成功すれば、trueを返してくれる。

バリデーションとテスト駆動開発

バリデーションとテスト駆動開発は相性が良く、まず失敗するテストを書き、次にテストを成功させるように実装すると、期待した通りに動いているかを確認することができる。

例:

test/models/user_test.rb
require 'test_helper'

class UserTest < ActiveSupport::TestCase

  def setup
    @user = User.new(name: "Example User", email: "[email protected]")
  end

  test "should be valid" do
    assert @user.valid?
  end

  test "name should be present" do
    @user.name = "     "
    assert_not @user.valid?
  end
end

setupメソッド@userを定義しておく。
setupメソッドの中の書かれた処理は各テストが走る直前に実行される。

@user.nameを空白にし、assert_notメソッドを使うことで有効性を確認できる。

まだ、validatesをかけていなければテストはREDになる。

以下のようにすることで、テストはGREENとなる。

app/models/user.rb
validates :name,  presence: true

メールの正規表現

email属性の場合は、有効なメールアドレスかどうかを判定するために、もっと厳重な要求を満たさなければらない。
空のアドレスに対してvalidatesするだけではなく、
[email protected]
にフォーマットが合っているかを確認する必要がある。
以下にそのテストを載せる。

例:
有効なメールアドレス

test/models/user_test.rb
test "email validation should accept valid addresses" do
    valid_addresses = %w[[email protected] [email protected] [email protected]
                         [email protected] [email protected]]
    valid_addresses.each do |valid_address|
      @user.email = valid_address
      assert @user.valid?, "#{valid_address.inspect} should be valid"
    end
end

無効なメールアドレス(,があったり、@がない)

test/models/user_test.rb
test "email validation should reject invalid addresses" do
    invalid_addresses = %w[user@example,com user_at_foo.org user.name@example.
                           foo@bar_baz.com foo@bar+baz.com]
    invalid_addresses.each do |invalid_address|
      @user.email = invalid_address
      assert_not @user.valid?, "#{invalid_address.inspect} should be invalid"
    end
end

assert @user.valid?, "#{valid_address.inspect} should be valid"
により、どのメールアドレスでテストが失敗したかわかるようにする。

このテストをGREENにするなら以下のようなvalidatesが必要になる。

app/models/user.rb
class User < ApplicationRecord
  #空白と長さに対するvalidatesを含む
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX }
end

他にも一意性を持たせないといけないが割愛。

セキュアなパスワード

セキュアパスワードという手法では、各ユーザーにパスワードとパスワードの確認を入力させ、それを (そのままではなく) ハッシュ化したものをデータベースに保存する。

ユーザーの認証は、パスワードの送信、ハッシュ化、データベース内のハッシュ化された値との比較、という手順で進む。

比較するのは生のパスワードではなく、ハッシュ化されたもの同士である。

そのためにhas_secure_passwordというメソッドを利用する。

このメソッドはUSERモデル内で呼びだすことができる。

class User < ApplicationRecord
  .
  .
  .
  has_secure_password
end

モデルにこのメソッドを追加することで、

・データベース内のpassword_digestというカラムにハッシュ化したパスワードを保存
・passwordとpassword_confirmationの利用
・authenticateメソッドが使用

が可能になる。

このメソッドを使用するにはデータベースにpassword_digestというカラムを追加する必要がある。
(マイグレーションファイルを作り、changeメソッド内に処理を書き、マイグレートする)

また、bcryptをインストールしていない場合は、Gemfileに記述し、bundle installを実行しておく。

authenticateメソッド

ハッシュ化されたもの同士を比較するにはauthenticateメソッドを利用する。
引数の文字列がパスワードと一致すれば、Userオブジェクトを、間違っていればfalseを返す。

>>user.authenticate("not_the_right_password")
false
>> user.authenticate("right_password")
ユーザーオブジェクトが返される

おわり

第六章は、メインはユーザー登録に対するバリデーションとそれに対するテストだった。
ここも必須の行程になるだろうな。

次↓
https://qiita.com/jonnyjonnyj1397/items/b1fb517fd922934cdd3e