LoginSignup
0
0

More than 1 year has passed since last update.

railsチュートリアル第11章 AccountActivationのデータモデル

Posted at

AccountActivationのデータモデル

ubuntu:~/environment/sample_app (account-activation) $ rails generate migration add_activation_to_users activation_digest:string activated:boolean activated_at:datetime
Running via Spring preloader in process 4751
      invoke  active_record
      create    db/migrate/20211017043743_add_activation_to_users.rb

Activationトークンのコールバック

アカウント有効化用の属性とインデックスを追加するマイグレーション

db/migrate/[timestamp]_add_activation_to_users.rb

class AddActivationToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :activation_digest, :string
    add_column :users, :activated, :boolean, default: false
    # activated属性のデフォルトの論理値をfalseにしておきます
    # 仮想属性の有効化トークンにアクセス
    add_column :users, :activated_at, :datetime
  end
end

Userモデルにアカウント有効化のコードを追加する

app/models/user.rb

class User < ApplicationRecord
  attr_accessor :remember_token, :activation_token
  before_save   :downcase_email
  before_create :create_activation_digest
  # トークンとそれに対応するダイジェストを割り当てる
.
.
.
  private

  # メールアドレスをすべて小文字にする
  def downcase_email
    self.email = email.downcase
  end

    # 有効化トークンとダイジェストを作成および代入する
  def create_activation_digest
  # Userモデル内でしか使わないので、外部に公開する必要ない。
    self.activation_token  = User.new_token
    self.activation_digest = User.digest(activation_token)
  end
end

サンプルユーザーの生成とテスト

サンプルデータとfixtureも更新し、テスト時のサンプルとユーザーを事前に有効化する

サンプルユーザーを最初から有効にしておく

db/seeds.rb

# メインのサンプルユーザーを1人作成する
User.create!(name:  "Example User",
             email: "example@railstutorial.org",
             password:              "foobar",
             password_confirmation: "foobar",
             admin: true,
             activated: true,
             activated_at: Time.zone.now)
# create!は基本的にcreateメソッドと同じものですが、
#   ユーザーが無効な場合にfalseを返すのではなく例外を発生させる
# admin:trueにして管理者にする
# サーバーのタイムゾーンに応じたタイムスタンプ

# 追加のユーザーをまとめて生成する
# メイン以外のユーザー99人を作成
99.times do |n|
  name  = Faker::Name.name
  email = "example-#{n+1}@railstutorial.org"
  # 数ごとにメアドが変更される
  password = "password"
  # パスワードは変わらない
  User.create!(name:  name,
               email: email,
               password:              password,
               password_confirmation: password,
               activated: true,
               activated_at: Time.zone.now)
  # 許可された属性リストにadminが含まれていない
  # 任意のユーザーが自分自身にアプリケーションの
  #   管理者権限を与えることを防止

end

fixtureのユーザーを有効にしておく

test/fixtures/users.yml

michael:
  name: Michael Example
  email: michael@example.com
  password_digest: <%= User.digest('password') %>
  admin: true
  activated: true
  activated_at: <%= Time.zone.now %>
  # サーバーのタイムゾーンに応じたタイムスタンプ

archer:
  name: Sterling Archer
  email: duchess@example.gov
  password_digest: <%= User.digest('password') %>
  activated: true
  activated_at: <%= Time.zone.now %>

lana:
  name: Lana Kane
  email: hands@example.gov
  password_digest: <%= User.digest('password') %>
  activated: true
  activated_at: <%= Time.zone.now %>

malory:
  name: Malory Archer
  email: boss@example.gov
  password_digest: <%= User.digest('password') %>
  activated: true
  activated_at: <%= Time.zone.now %>

<% 30.times do |n| %>
# さらに30人のユーザーを追加
user_<%= n %>:
  name:  <%= "User #{n}" %>
  email: <%= "user-#{n}@example.com" %>
  password_digest: <%= User.digest('password') %>
  activated: true
  activated_at: <%= Time.zone.now %>
<% end %>

演習

1.
本項での変更を加えた後、テストスイートが green のままになっていることを確認してみましょう。

ubuntu:~/environment/sample_app (account-activation) $ rails t
Running via Spring preloader in process 9538
Started with run options --seed 13465

  43/43: [============================] 100% Time: 00:00:03, Time: 00:00:03

Finished in 3.52011s
43 tests, 168 assertions, 0 failures, 0 errors, 0 skips

2.
コンソールからUserクラスのインスタンスを生成し、そのオブジェクトからcreate_activation_digestメソッドを呼び出そうとすると(Privateメソッドなので)NoMethodErrorが発生することを確認してみましょう。また、そのUserオブジェクトからダイジェストの値も確認してみましょう。

ubuntu:~/environment/sample_app (account-activation) $ rails console
Running via Spring preloader in process 9590
Loading development environment (Rails 6.0.3)
>> User.create_activate_digest
Traceback (most recent call last):
        1: from (irb):1
NoMethodError (undefined method `create_activate_digest' for User (call 'User.connection' to establish a connection):Class)

3.
リスト 6.34で、メールアドレスの小文字化にはemail.downcase!という(代入せずに済む)メソッドがあることを知りました。このメソッドを使って、リスト 11.3のdowncase_emailメソッドを改良してみてください。また、うまく変更できれば、テストスイートは成功したままになっていることも確認してみてください。

class User < ApplicationRecord
.
.
.
  #private

  # メールアドレスをすべて小文字にする
    def downcase_email
      email.downcase!
    end
.
.
.
end
ubuntu:~/environment/sample_app (account-activation) $ rails t
Running via Spring preloader in process 11264
Started with run options --seed 11907

  43/43: [============================] 100% Time: 00:00:02, Time: 00:00:02

Finished in 2.14029s
43 tests, 168 assertions, 0 failures, 0 errors, 0 skips
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0