0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Ruby on Rails Tutorial 11章

Posted at

11.1.1

演習
現時点でテストスイートを実行すると greenになることを確認してみましょう。
表 11.2の名前付きルートでは、_pathではなく_urlを使うように記してあります。なぜでしょうか? 考えてみましょう。ヒント: 私達はこれからメールで名前付きルートを使います。

1確認
2メールからリンクを開いてアクセスするため

11.1.2

演習
本項での変更を加えた後、テストスイートが green のままになっていることを確認してみましょう。
コンソールからUserクラスのインスタンスを生成し、そのオブジェクトからcreate_activation_digestメソッドを呼び出そうとすると (Privateメソッドなので) NoMethodErrorが発生することを確認してみましょう。また、そのUserオブジェクトからダイジェストの値も確認してみましょう。
リスト 6.34で、メールアドレスの小文字化にはemail.downcase!という (代入せずに済む) メソッドがあることを知りました。このメソッドを使って、リスト 11.3のdowncase_emailメソッドを改良してみてください。また、うまく変更できれば、テストスイートは成功したままになっていることも確認してみてください。

1確認


>> user = User.new
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil, password_digest: nil, remember_digest: nil, admin: false, activation_digest: nil, activated: false, activated_at: nil>
>> user.create_activation_digest
Traceback (most recent call last):
        1: from (irb):2
NoMethodError (private method `create_activation_digest' called for #<User:0x00000000032badb0>)
Did you mean?  restore_activation_digest!


3

    def downcase_email
      self.email.downcase!
    end

selfをつけなくてもテストでエラーは出ないが

modelクラスの中でのselfの使い方
によると

ちなみに使い分けですが、インスタンスメソッドはそれぞれのインスタンスに対して参照・更新するようなメソッドとして使います。一方クラスメソッドは、modelクラスのレコードを検索するとか、作成されたインスタンスの数をカウントするとか、クラスの新しいインスタンスを作る等、個々のインスタンスには紐づけずクラスに対して働きかけるメソッドになります。

とあるのでクラスメソッドにした方がいいのではないかなと思う
create_activation_digestもself.ついてるので
しかしインスタントメソッド内でself.をつかうとインスタすメソッドになるのでこれはクラスメソッドにするためのselfではない??
class<<self
endで囲われてなかったり
def User.~となっていなかったりdef self.~やメソッド内でself.class.hoge~となっていないのでクラスメソッドではないと判断したが会っているのかな?

11.2.1

演習
コンソールを開き、CGIモジュールのescapeメソッド (リスト 11.15) でメールアドレスの文字列をエスケープできることを確認してみましょう。このメソッドで"Don’t panic!"をエスケープすると、どんな結果になりますか?

>> CGI.escape('Don’t panic!')
=> "Don%E2%80%99t+panic%21"

11.2.2

演習
Railsのプレビュー機能を使って、ブラウザから先ほどのメールを表示してみてください。「Date」の欄にはどんな内容が表示されているでしょうか?

Mon, 22 Apr 2019 01:44:05 +0000
GMT時間でアクセスした日時表示

11.2.3
演習
この時点で、テストスイートが greenになっていることを確認してみましょう。
リスト 11.20で使ったCGI.escapeの部分を削除すると、テストが redに変わることを確認してみましょう。

確認

n----==_mimepart_5cbd2c00cb0fa_140cbc99a4665c3\r\nContent-Type: text/plain;\r\n charset=UTF-8\r\nContent-Transfer-Encoding: 7bit\r\n\r\nHi Michael Example,\r\n\r\nWelcome to the Sample App! Click on the link below to activate your account:\r\n\r\nhttp://dfa974f98d004f37899984bee93a2473.vfs.cloud9.us-east-2.amazonaws.com/account_activations/cmK5mEK4rCiqcyWEM67KyA/edit?email=michael%40example.com\r\n\r\n----==_mimepart_5cbd2c00cb0fa_140cbc99a4665c3\r\nContent-Type: text/html;\r\n charset=UTF-8\r\nContent-Transfer-Encoding: 7bit\r\n\r\n<!DOCTYPE html>\r\n<html>\r\n  <head>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\r\n    <style>\r\n      /* Email styles need to be inline */\r\n    </style>\r\n  </head>\r\n\r\n  <body>\r\n    <h1>Sample App</h1>\r\n\r\n<p>Hi Michael Example,</p>\r\n\r\n<p>\r\nWelcome to the Sample App! Click on the link below to activate your account:\r\n</p>\r\n\r\n<a href=\"http://dfa974f98d004f37899984bee93a2473.vfs.cloud9.us-east-2.amazonaws.com/account_activations/cmK5mEK4rCiqcyWEM67KyA/edit?email=michael%40example.com\">Activate</a>\r\n  </body>\r\n</html>\r\n\r\n----==_mimepart_5cbd2c00cb0fa_140cbc99a4665c3--\r\n".
        test/mailers/user_mailer_test.rb:14:in `block in <class:UserMailerTest>'

  41/41: [=========] 100% Time: 00:00:01, Time: 00:00:01

Finished in 1.55150s
41 tests, 171 assertions, 1 failures, 0 errors, 0 skips


11.2.4

演習
新しいユーザーを登録したとき、リダイレクト先が適切なURLに変わったことを確認してみましょう。その後、Railsサーバーのログから送信メールの内容を確認してみてください。有効化トークンの値はどうなっていますか?
コンソールを開き、データベース上にユーザーが作成されたことを確認してみましょう。また、このユーザーはデータベース上にはいますが、有効化のステータスがfalseのままになっていることを確認してください。

1
Redirected to https://dfa974f98d004f37899984bee93a2473.vfs.cloud9.us-east-2.amazonaws.com/
ルートディレクトリになっている

2


>> user = User.find(101)
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 101], ["LIMIT", 1]]
=> #<User id: 101, name: "test01", email: "test01@example.org", created_at: "2019-04-22 05:18:28", updated_at: "2019-04-22 05:18:28", password_digest: "$2a$10$rPJDdcoRU/M9dkyv/X5hKehWF24P25FKLFq4mIPWA4T...", remember_digest: nil, admin: false, activation_digest: "$2a$10$IyKVaC6xJh2zfGTywkFUhuaY8JnePJer1j4jKPFYsJw...", activated: false, activated_at: nil>
>> user.activated?
=> false


11.3.1

演習
コンソール内で新しいユーザーを作成してみてください。新しいユーザーの記憶トークンと有効化トークンはどのような値になっているでしょうか? また、各トークンに対応するダイジェストの値はどうなっているでしょうか?
リスト 11.26で抽象化したauthenticated?メソッドを使って、先ほどの各トークン/ダイジェストの組み合わせで認証が成功することを確認してみましょう。

>> user = User.create(name: "test1131",email: "test@mail.org", password: "123456")                              
   (0.1ms)  begin transaction
  User Exists (0.3ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) LIMIT ?  [["email", "test@mail.org"], ["LIMIT", 1]]
  SQL (2.8ms)  INSERT INTO "users" ("name", "email", "created_at", "updated_at", "password_digest", "activation_digest") VALUES (?, ?, ?, ?, ?, ?)  [["name", "test1131"], ["email", "test@mail.org"], ["created_at", "2019-04-22 09:15:50.439813"], ["updated_at", "2019-04-22 09:15:50.439813"], ["password_digest", "$2a$10$Vz24S0K53ErWqPOMThXBbOLJ5c.IqzV4LhT2Am07tNANWysk9vrUq"], ["activation_digest", "$2a$10$glOElS8hLRrrL7S6oU7HbeGa2YNAK8SY6eNmz4Y3ebu6LI3bw5ky2"]]
   (7.2ms)  commit transaction
=> #<User id: 102, name: "test1131", email: "test@mail.org", created_at: "2019-04-22 09:15:50", updated_at: "2019-04-22 09:15:50", password_digest: "$2a$10$Vz24S0K53ErWqPOMThXBbOLJ5c.IqzV4LhT2Am07tNA...", remember_digest: nil, admin: false, activation_digest: "$2a$10$glOElS8hLRrrL7S6oU7HbeGa2YNAK8SY6eNmz4Y3ebu...", activated: false, activated_at: nil>
>> user.remember_token
=> nil
>> user.activation_token
=> "cCxeiFM8zoy1ziofmOnrcA"
>> user.remember_digest
=> nil
>> user.activation_digest
=> "$2a$10$glOElS8hLRrrL7S6oU7HbeGa2YNAK8SY6eNmz4Y3ebu6LI3bw5ky2"
>> 

2

>> user.remember_token = User.new_token
=> "ixM6QvBSTvD-UIFn16IpvA"
>> user.update_attribute(:remember_digest, User.digest(user.remember_token))
   (0.1ms)  begin transaction
  SQL (2.6ms)  UPDATE "users" SET "updated_at" = ?, "remember_digest" = ? WHERE "users"."id" = ?  [["updated_at", "2019-04-23 11:33:13.345380"], ["remember_digest", "$2a$10$Blp7ueOFh/3xEb9iErYT1uwR9I6T4qo0SrFuqBH0i9Y1ddAApScyC"], ["id", 102]]
   (5.7ms)  commit transaction
=> true

11.3.3
演習
リスト 11.35にあるactivateメソッドはupdate_attributeを2回呼び出していますが、これは各行で1回ずつデータベースへ問い合わせしていることになります。リスト 11.39に記したテンプレートを使って、update_attributeの呼び出しを1回のupdate_columns呼び出しにまとめてみましょう (これでデータベースへの問い合わせが1回で済むようになります)。また、変更後にテストを実行し、 greenになることも確認してください。

現在は、/usersのユーザーindexページを開くとすべてのユーザーが表示され、/users/:idのようにIDを指定すると個別のユーザーを表示できます。しかし考えてみれば、有効でないユーザーは表示する意味がありません。そこで、リスト 11.40のテンプレートを使って、この動作を変更してみましょう9。なお、ここで使っているActive Recordのwhereメソッドについては、13.3.3でもう少し詳しく説明します。

ここまでの演習課題で変更したコードをテストするために、/users と /users/:id の両方に対する統合テストを作成してみましょう。


update_columns(activated: true, activated_at: Time.zone.now)

def index
@users = User.where(activated: ture).paginate(page: params[:page])
end

def show
@user = User.find(params[:id])
redirect_to root_url and return unless @user.activated?
end

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?