Railsチュートリアル 第6章

6.1 Userモデル

6.1.1

演習1

schema.rbの内容は以下の通りです.

ActiveRecord::Schema.define(version: 2018_06_25_044152) do

  create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
    t.string "name"
    t.string "email"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

end

演習2, 3

省略.

6.1.2

演習1, 2

以下のコマンドを実行し, コンテナの中に入ります.

$ docker-compose exec web bash

Railsの対話モードに入ります.

$ rails console

クラスについて調べます.

>> user = User.new
   (0.5ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil>

>> user.class.superclass
=> ApplicationRecord(abstract)
>> user.class.superclass.superclass
=> ActiveRecord::Base

6.1.3

演習1

たしかにStringクラスです.

>> user = User.new(name: "Michael Hartl", email: "mhartl@example.com")
=> #<User id: nil, name: "Michael Hartl", email: "mhartl@example.com", created_at: nil, updated_at: nil>

>> user.name.class
=> String
>> user.email.class
=> String

演習2

こんな感じです.

>> user.created_at.class
=> ActiveSupport::TimeWithZone
>> user.updated_at.class
=> ActiveSupport::TimeWithZone

6.1.4

演習1

find_by_nameメソッドも使えました.

>> User.find_by(name: "Michael Hartl")
  User Load (0.8ms)  SELECT  `users`.* FROM `users` WHERE `users`.`name` = 'Michael Hartl' LIMIT 1
=> #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com", created_at: "2018-06-25 05:01:54", updated_at: "2018-06-25 05:01:54">

>> User.find_by_name("Michael Hartl")
  User Load (0.9ms)  SELECT  `users`.* FROM `users` WHERE `users`.`name` = 'Michael Hartl' LIMIT 1
=> #<User id: 1, name: "Michael Hartl", email: "mhartl@example.com", created_at: "2018-06-25 05:01:54", updated_at: "2018-06-25 05:01:54">

演習2, 3

>> User.all.class
=> User::ActiveRecord_Relation

>> User.all.length
  User Load (1.0ms)  SELECT `users`.* FROM `users`
=> 2

6.1.5

演習1

>> user.name = "Michael Jackson"
=> "Michael Jackson"

>> user.save
   (0.6ms)  SAVEPOINT active_record_1
  User Update (1.0ms)  UPDATE `users` SET `name` = 'Michael Jackson', `updated_at` = '2018-06-25 05:23:28' WHERE `users`.`id` = 1
   (0.6ms)  RELEASE SAVEPOINT active_record_1
=> true

演習2

>> user.update_attributes(email: "mjackson@example.com")
   (0.6ms)  SAVEPOINT active_record_1
  User Update (0.6ms)  UPDATE `users` SET `email` = 'mjackson@example.com', `updated_at` = '2018-06-25 05:24:00' WHERE `users`.`id` = 1
   (0.9ms)  RELEASE SAVEPOINT active_record_1
=> true

演習3

>> user.created_at = 1.year.ago
=> Sun, 25 Jun 2017 05:24:28 UTC +00:00

6.2 ユーザーを検証する

6.2.1

省略.

6.2.2

演習1

nameemailは空白であってはならないからですね.

>> u = User.new
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil>
>> u.valid?
=> false
>> u.errors.full_messages
=> ["Name can't be blank", "Email can't be blank"]

演習2

ハッシュに使われているキーがシンボルであることに注意すると, 以下のようにエラーメッセージを取得することができます.

>> u.errors.messages
=> {:name=>["can't be blank"], :email=>["can't be blank"]}
>> u.errors.messages[:email]
=> ["can't be blank"]

6.2.3

演習1, 2

以下のようなエラーメッセージが得られます.

>> u = User.new
=> #<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil>
>> u.name = "a"*51
=> "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
>> u.valid?
=> false
>> u.errors.full_messages
=> ["Name is too long (maximum is 50 characters)", "Email can't be blank"]

6.2.4

省略.

6.2.5

  • アプリケーションレベルの一意性
  • データベースレベルの一意性
  • インデックス
  • コールバックメソッド などかなり盛りだくさんなセクションでしたが, チュートリアル通りに進めればよいだけなので, 省略します.

    6.3 セキュアなパスワードを追加する

    6.3.1

    パスワード保存用のカラムをマイグレーションファイルに定義してdb:migrate. ここまでしっかりやってくれば予想ができる手順ですね. それにしてもhas_secure_passwordの万能感がハンパないです.

    6.3.2

    rails consoleにて確かめました.

>> user = User.new(name: "Michael Hartl", email: "mhartl@example.com")
=> #<User id: nil, name: "Michael Hartl", email: "mhartl@example.com", created_at: nil, updated_at: nil, password_digest: nil>
>> user.valid?
=> false
>> user.errors.full_messages
=> ["Password can't be blank"]

6.3.3

rails consoleにて確かめました.

>> user = User.new
>> user.name = "Foo"
>> user.email = "foo@bar.com"
>> user.password = "pass"

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

6.3.4

演習1

まずはUserを作り, 保存します.

>> user = User.new(name: "Michael Hartl", email: "mhartl@example.com", password: "foobar", password_confirmation: "foobar")

>> user.save

一旦exitしてから再びconsoleを起動します. 検索してみると確かにさっき保存したレコードが存在しますね.

>> user = User.find_by_name("Michael Hartl")
=> #<User id: 4, name: "Michael Hartl", email: "mhartl@example.com", created_at: "2018-06-25 09:33:51", updated_at: "2018-06-25 09:33:51", password_digest: "$2a$10$tM4ebAaSFIzfhqzi6.Lo/Ofs6/TfKpnP7LrgkCRV/z0...">

演習2

名前を書き換えて保存を試みます.

>> user.name = "Michael Jackson"
=> "Michael Jackson"
>> user.save
=> false
>> user.errors.full_messages
=> ["Password can't be blank", "Password is too short (minimum is 6 characters)"]

パスワードを要求されてしまいました. データを更新するには認証が必要ということでしょうかね.

演習3

検証を回避しつつデータを更新する方法が, 6.1.5に書かれています.

>> user.update_attribute(:name, "Michael Jackson")
=> true