Ruby
Rails
RubyOnRails
Railsチュートリアル

Ruby on Rails チュートリアル 5.0(第4版)6.3演習

Ruby on Rails チュートリアル 5.0(第4版)を学習中です。
演習問題を自分なりに実施しました。
もし間違い等あればコメントいただけると嬉しいです。

演習6.3.2.1

<問題>
この時点では、userオブジェクトに有効な名前とメールアドレスを与えても、valid?で失敗してしまうことを確認してみてください。

<解答>

>> user=User.new(name:"Taro Yamada",email:"yamada@mail.com")
=> #<User id: nil, name: "Taro Yamada", email: "yamada@mail.com", created_at: nil, updated_at: nil, password_digest: nil>

>> user.valid?
  User Exists (0.2ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) LIMIT ?  [["email", "yamada@mail.com"], ["LIMIT", 1]]
=> false

演習6.3.2.2

<問題>
なぜ失敗してしまうのでしょうか? エラーメッセージを確認してみてください。

<解答>

>> user.errors.full_messages
=> ["Password can't be blank"]

演習6.3.3.1

<問題>
有効な名前とメールアドレスでも、パスワードが短すぎるとuserオブジェクトが有効にならないことを確認してみましょう。

<解答>

>> user=User.new(name:"Taro Yamada",email:"yamada@mail.com",password:"12345")
=> #<User id: nil, name: "Taro Yamada", email: "yamada@mail.com", created_at: nil, updated_at: nil, password_digest: "$2a$10$W699oKChtVu6Hd2D4uDSsOb9KI6i0HiDcNvobt7xhfW...">

>> user.valid?
  User Exists (0.3ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) LIMIT ?  [["email", "yamada@mail.com"], ["LIMIT", 1]]
=> false

演習6.3.3.2

<問題>
上で失敗した時、どんなエラーメッセージになるでしょうか? 確認してみましょう。

<解答>

>> user.errors.full_messages
=> ["Password is too short (minimum is 6 characters)"]

演習6.3.4.1

<問題>
コンソールを一度再起動して (userオブジェクトを消去して)、このセクションで作ったuserオブジェクトを検索してみてください。

<解答>

>> user = User.find_by(email: "mhartl@example.com")
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "mhartl@example.com"], ["LIMIT", 1]]
=> #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com", created_at: "2017-02-05 02:01:37", updated_at: "2017-02-05 02:01:37", password_digest: "$2a$10$E.gAC.d0Ch5dvmrM6vnNhu6gIpNtwFD8JhHmKPyc/V3...">

演習6.3.4.2

<問題>
オブジェクトが検索できたら、名前を新しい文字列に置き換え、saveメソッドで更新してみてください。うまくいきませんね...、なぜうまくいかなかったのでしょうか?

<解答>

>> user.name="Yamada"
=> "Yamada"

>> user.save
   (0.2ms)  begin transaction
  User Exists (0.2ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) AND ("users"."id" != ?) LIMIT ?  [["email", "mhartl@example.com"], ["id", 1], ["LIMIT", 1]]
   (0.1ms)  rollback transaction
=> false

name属性を変更し、.saveを実行すると、変更していない箇所も全て保存を要求される。
すなわち、パスワードをレコードに保存することを要求するため、エラーが生じる。
変更及び保存をname属性のみに限定する必要がある。(6.3.4.3参照)

演習6.3.4.3

<問題>
今度は6.1.5で紹介したテクニックを使って、userの名前を更新してみてください。

<解答>

>> user.update_attribute(:name, "Yamada")
   (0.1ms)  begin transaction
  SQL (0.4ms)  UPDATE "users" SET "name" = ?, "updated_at" = ? WHERE "users"."id" = ?  [["name", "Yamada"], ["updated_at", 2017-02-05 02:36:54 UTC], ["id", 1]]
   (10.0ms)  commit transaction
=> true

"updated_at"が更新されており、保存がうまくいったことがわかる。

関連記事

Ruby on Rails チュートリアル 完全攻略 概要と演習解答総まとめ
http://mochikichi.hatenablog.com/entry/rails_tutorial_guide