まずば作業用のブランチ作成。
git checkout -b modeling-users
Railsはデータ行で構成されるテーブルからなり、各行はデータ属性のカラム (列) を持ちます。らしい。コンソールでつくるとはちがうと。
rails generate model User name:string email:string
で、
Running via Spring preloader in process 4292
invoke active_record
create db/migrate/20200505013551_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
マイグレーションファイルが生成されていることを確認。
class CreateUsers < ActiveRecord::Migration[5.1]
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
そしておきまりの
rails db:migrate
で
== 20200505013551 CreateUsers: migrating ======================================
-- create_table(:users)
-> 0.0019s
== 20200505013551 CreateUsers: migrated (0.0024s) =============================
ここでついにdbをみるためのツールをいれるらしい。
DB Browser for SQLiteというらしい。
どこにDLするかなどがちゃがちゃ出てくるがここは適当で。
で、DLしても開くアプリに指定されてないとか、指定しようとしても出てこないとかすったもんだ。ズーン。
アプリを立ち上げ、そのアプリからDLしたファイルを指定してひらくという方法で解決。
データモデルを調べてみましょう。(この時点では) データベースを変更したくないので、コンソールをサンドボックスモードで起動
rails console --sandbox
すると
Running via Spring preloader in process 5608
Loading development environment in sandbox (Rails 5.1.6)
Any modifications you make will be rolled back on exit
ここからはいろいろお試しけい
User.new
で
#<User id: nil, name: nil, email: nil, created_at: nil, updated_at: nil>
すべてnil
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.valid?
で
true
変数userはtrueですよと。
user.save
で
(0.1ms) SAVEPOINT active_record_1
SQL (5.5ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "Michael Hartl"], ["email", "mhartl@example.com"], ["created_at", "2020-05-05 02:19:06.707948"], ["updated_at", "2020-05-05 02:19:06.707948"]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true
きちんとセーブされましたと。
user
変数を出力すると
#<User id: 1, name: "Michael Hartl", email: "mhartl@example.com", created_at: "2020-05-05 02:19:06", updated_at: "2020-05-05 02:19:06">
先ほどセーブしたのがでますよと。
>> user.name
=> "Michael Hartl"
>> user.email
=> "mhartl@example.com"
>> user.updated_at
=> Tue, 05 May 2020 02:19:06 UTC +00:00
いろいろためしても大丈夫ですよと。
さらに、変数作成とセーブを一気に行うときは
>> User.create(name: "A Nother", email: "another@example.org")
(1.2ms) SAVEPOINT active_record_1
SQL (0.7ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "A Nother"], ["email", "another@example.org"], ["created_at", "2020-05-05 02:22:36.877978"], ["updated_at", "2020-05-05 02:22:36.877978"]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> #<User id: 2, name: "A Nother", email: "another@example.org", created_at: "2020-05-05 02:22:36", updated_at: "2020-05-05 02:22:36">
という、createでいっぱつでいけますと。
※打ち込みと結果をセットで書くようにかえます
もう一つ設定しましょう
foo = User.create(name: "Foo", email: "foo@bar.com")
(0.1ms) SAVEPOINT active_record_1
SQL (0.1ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "Foo"], ["email", "foo@bar.com"], ["created_at", "2020-05-05 02:24:12.356159"], ["updated_at", "2020-05-05 02:24:12.356159"]]
(0.0ms) RELEASE SAVEPOINT active_record_1
=> #<User id: 3, name: "Foo", email: "foo@bar.com", created_at: "2020-05-05 02:24:12", updated_at: "2020-05-05 02:24:12">
destroyはcreateの逆です。
foo.destroy
(0.1ms) SAVEPOINT active_record_1
SQL (0.1ms) DELETE FROM "users" WHERE "users"."id" = ? [["id", 3]]
(0.0ms) RELEASE SAVEPOINT active_record_1
=> #<User id: 3, name: "Foo", email: "foo@bar.com", created_at: "2020-05-05 02:24:12", updated_at: "2020-05-05 02:24:12">
まずば作業用のブランチ作成。
git checkout -b modeling-users
Railsはデータ行で構成されるテーブルからなり、各行はデータ属性のカラム (列) を持ちます。らしい。コンソールでつくるとはちがうと。
rails generate model User name:string email:string
で、
Running via Spring preloader in process 4292
invoke active_record
create db/migrate/20200505013551_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
マイグレーションファイルが生成されていることを確認。
class CreateUsers < ActiveRecord::Migration[5.1]
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
そしておきまりの
rails db:migrate
で
== 20200505013551 CreateUsers: migrating ======================================
-- create_table(:users)
-> 0.0019s
== 20200505013551 CreateUsers: migrated (0.0024s) =============================
ここでついにdbをみるためのツールをいれるらしい。
DB Browser for SQLiteというらしい。
どこにDLするかなどがちゃがちゃ出てくるがここは適当で。
で、DLしても開くアプリに指定されてないとか、指定しようとしても出てこないとかすったもんだ。ズーン。
アプリを立ち上げ、そのアプリからDLしたファイルを指定してひらくという方法で解決。
データモデルを調べてみましょう。(この時点では) データベースを変更したくないので、コンソールをサンドボックスモードで起動
rails console --sandbox
すると
Running via Spring preloader in process 5608
Loading development environment in sandbox (Rails 5.1.6)
Any modifications you make will be rolled back on exit
ここからはいろいろお試しけい
User.new
で
#
すべてnil
user = User.new(name: "Michael Hartl", email: "mhartl@example.com")
で
#
きちんと情報はいりますよと。
user.valid?
で
true
変数userはtrueですよと。
user.save
で
(0.1ms) SAVEPOINT active_record_1
SQL (5.5ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "Michael Hartl"], ["email", "mhartl@example.com"], ["created_at", "2020-05-05 02:19:06.707948"], ["updated_at", "2020-05-05 02:19:06.707948"]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true
きちんとセーブされましたと。
user
変数を出力すると
#
先ほどセーブしたのがでますよと。
user.name
=> "Michael Hartl"
user.email
=> "mhartl@example.com"
user.updated_at
=> Tue, 05 May 2020 02:19:06 UTC +00:00
いろいろためしても大丈夫ですよと。
さらに、変数作成とセーブを一気に行うときは
User.create(name: "A Nother", email: "another@example.org")
(1.2ms) SAVEPOINT active_record_1
SQL (0.7ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "A Nother"], ["email", "another@example.org"], ["created_at", "2020-05-05 02:22:36.877978"], ["updated_at", "2020-05-05 02:22:36.877978"]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> #
という、createでいっぱつでいけますと。
※打ち込みと結果をセットで書くようにかえます
もう一つ設定しましょう
foo = User.create(name: "Foo", email: "foo@bar.com")
(0.1ms) SAVEPOINT active_record_1
SQL (0.1ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "Foo"], ["email", "foo@bar.com"], ["created_at", "2020-05-05 02:24:12.356159"], ["updated_at", "2020-05-05 02:24:12.356159"]]
(0.0ms) RELEASE SAVEPOINT active_record_1
=> #
destroyはcreateの逆です。
foo.destroy
(0.1ms) SAVEPOINT active_record_1
SQL (0.1ms) DELETE FROM "users" WHERE "users"."id" = ? [["id", 3]]
(0.0ms) RELEASE SAVEPOINT active_record_1
=> #
削除されたオブジェクトは次のようにまだメモリ上に残っています。
え、そうなんや
foo
=> #
残ってた。
では、オブジェクトが本当に削除されたかどうかをどのようにして知ればよいのでしょうか。そして、保存して削除されていないオブジェクトの場合、どうやってデータベースからユーザーを取得するのでしょうか。これらの問いに答えるためには、Active Recordを使ってUserオブジェクトを検索する方法について学ぶ必要があります。
なるへそー。
まずはいる人から探していきましょう。
User.find(1)
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
=> #
つづいてさっき消したfooさん、三人目をさがす
User.find(3)
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]]
Traceback (most recent call last):
1: from (irb):14
ActiveRecord::RecordNotFound (Couldn't find User with 'id'=3)
みつかりませんですた。
読み返したけど、メモリに残っています。の意味がよくわからん。
すくなくともDBにはいなかったと。
で、先に進む。
User.find_by(email: "mhartl@example.com")
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT ? [["email", "mhartl@example.com"], ["LIMIT", 1]]
=> #
User.first
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #
User.all
User Load (0.2ms) SELECT "users".* FROM "users" LIMIT ? [["LIMIT", 11]]
=> #, #]>
いろいろなDBからの抜き方があるよという話。
つづいて、更新の手法に関して。
user
=> #
user.email = "mhartl@example.net"
=> "mhartl@example.net"
user.save
(0.1ms) SAVEPOINT active_record_1
SQL (0.2ms) UPDATE "users" SET "email" = ?, "updated_at" = ? WHERE "users"."id" = ? [["email", "mhartl@example.net"], ["updated_at", "2020-05-05 02:34:32.979629"], ["id", 1]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true
セーブはしましょう。しないと
user.email
=> "mhartl@example.net"
user.email = "foo@bar.com"
=> "foo@bar.com"
user.reload.email
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
=> "mhartl@example.net"
次のように変更が取り消されます。
user.created_at
=> Tue, 05 May 2020 02:19:06 UTC +00:00
user.updated_at
=> Tue, 05 May 2020 02:34:32 UTC +00:00
この辺も更新セーブで更新されますよ。
もう一つの更新方法に関して
user.update_attributes(name: "The Dude", email: "dude@abides.org")
(0.1ms) SAVEPOINT active_record_1
SQL (0.1ms) UPDATE "users" SET "email" = ?, "updated_at" = ?, "name" = ? WHERE "users"."id" = ? [["email", "dude@abides.org"], ["updated_at", "2020-05-05 02:36:56.590964"], ["name", "The Dude"], ["id", 1]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true
user.name
=> "The Dude"
user.email
=> "dude@abides.org"
update_attributesをつかう方法もあります。
これはプロゲートにはなかったなー
保存に成功した場合はtrueを返します。なりほど。
user.update_attribute(:name, "El Duderino")
(0.1ms) SAVEPOINT active_record_1
SQL (0.1ms) UPDATE "users" SET "updated_at" = ?, "name" = ? WHERE "users"."id" = ? [["updated_at", "2020-05-05 02:39:28.513301"], ["name", "El Duderino"], ["id", 1]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> true
user.name
=> "El Duderino"
特定の要素だけの更新でもOK。
パスワードとかはいってくると複数更新しようと思うと検証がはいってだめらしい。
よくわからんけど。
つづいてヴァリデーションのはなし。
具体的なテスト方法についてですが、まず有効なモデルのオブジェクトを作成し、その属性のうちの1つを有効でない属性に意図的に変更します。そして、バリデーションで失敗するかどうかをテストする、といった方針で進めていきます。念のため、最初に作成時の状態に対してもテストを書いておき、最初のモデルが有効であるかどうかも確認しておきます。このようにテストすることで、バリデーションのテストが失敗したとき、バリデーションの実装に問題があったのか、オブジェクトそのものに問題があったのかを確認することができます。
なるほど。
モデルを作成したときにUser用テストの原型ができているはずなので、まずはその中身から見ていきましょう、はい。
ややこしいのですが、、、
まず
有効なオブジェクトに対してテストを書くために、setupという特殊なメソッドを使って有効なUserオブジェクト (@user) を作成します (このメソッドは第3章の演習でも少し取り上げました)。setupメソッド内に書かれた処理は、各テストが走る直前に実行されます。@userはインスタンス変数ですが、setupメソッド内で宣言しておけば、すべてのテスト内でこのインスタンス変数が使えるようになります。したがって、valid?メソッドを使ってUserオブジェクトの有効性をテストすることができます (6.1.3)。作成したコードをリスト 6.5に示します。
ここにきてVALIDのはなし。振り返ってみると
Active Recordを理解する上で、「有効性 (Validity)」という概念も重要です。6.2で詳細について解説しますが、今はまず先ほどのuserオブジェクトが有効かどうか確認してみましょう。確認するためにはvalid?メソッドを使います。
現時点ではまだデータベースにデータは格納されていません。つまり、User.newはメモリ上でオブジェクトを作成しただけで、user.valid?という行はただオブジェクトが有効かどうかを確認しただけとなります (データベースにデータがあるかどうかは有効性には関係ありません)。データベースにUserオブジェクトを保存するためには、userオブジェクトからsaveメソッドを呼び出す必要があります。
なるほど。さっきの疑問のメモリが解決。DBには保存されていないがメモリにおりますと。
で、テストではそのメモリでやりますよと。
require 'test_helper'
class UserTest < ActiveSupport::TestCase
def setup
@user = User.new(name: "Example User", email: "user@example.com")
end
test "should be valid" do
assert @user.valid?
end
end
書き換えます。
で、テストします。
rails test:models
Traceback (most recent call last):
1: from (irb):31
NameError (undefined local variable or method `models' for main:Object)
Did you mean? module
ここでエラー。調べていると、ははーんなるほどsandboxのなかにいるからだなと理解。
ctrl+Dででる。
ec2-user:~/environment/sample_app (modeling-users) $ rails test:models
Started with run options --seed 64415
1/1: [===================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.02989s
1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
OK。
つづいてテストで@nameに空白いれたらテストしたらどうなるか検証。
require 'test_helper'
class UserTest < ActiveSupport::TestCase
def setup
@user = User.new(name: "Example User", email: "user@example.com")
end
test "should be valid" do
assert @user.valid?
end
test "name should be present" do
@user.name = " "
assert_not @user.valid?
end
end
で、テストで
ec2-user:~/environment/sample_app (modeling-users) $ rails test:models
Started with run options --seed 55918
FAIL["test_name_should_be_present", UserTest, 0.018388186999800382]
test_name_should_be_present#UserTest (0.02s)
Expected true to be nil or false
test/models/user_test.rb:15:in `block in class:UserTest'
2/2: [===================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.02143s
2 tests, 2 assertions, 1 failures, 0 errors, 0 skips
エラー。
ユーザーモデルにバリデーション追加
class User < ApplicationRecord
validates :name, presence: true
end
ここで再度検証。
ec2-user:~/environment/sample_app (modeling-users) $ rails console --sandbox
Running via Spring preloader in process 7262
Loading development environment in sandbox (Rails 5.1.6)
Any modifications you make will be rolled back on exit
user = User.new(name: "", email: "mhartl@example.com")
=> #
user.valid?
=> true
user.valid?
=> true
trueが出てしまった!!!こまった。
たぶんコード更新を保存できてないからだと直感。
サンドボックスをでて、再度保存してから同じことを実行。
(0.1ms) rollback transaction
ec2-user:~/environment/sample_app (modeling-users) $ rails console --sandbox
Running via Spring preloader in process 7317
Loading development environment in sandbox (Rails 5.1.6)
Any modifications you make will be rolled back on exit
user = User.new(name: "", email: "mhartl@example.com")
=> #
user.valid?
=> false
成功。
ヴァリデーションがたくさんできたときはどこでしくったかをみたければエラーを確認
user.errors.full_messages
=> ["Name can't be blank"]
プロゲートでこれって、お決まりのメッセージがでるものみたいな扱いだったけどちがうんかな。
ユーザーオブジェクトはセーブできないはすです。
user.save
(0.1ms) SAVEPOINT active_record_1
(0.1ms) ROLLBACK TO SAVEPOINT active_record_1
=> false
はい、できませんでした。オブジェクトの意味がまだわからん。
サンドボックスでてテスト
ec2-user:~/environment/sample_app (modeling-users) $ rails test:models
Started with run options --seed 21386
2/2: [===================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.02445s
2 tests, 2 assertions, 0 failures, 0 errors, 0 skips
完了。ながいなこれ
require 'test_helper'
class UserTest < ActiveSupport::TestCase
def setup
@user = User.new(name: "Example User", email: "user@example.com")
end
test "should be valid" do
assert @user.valid?
end
test "name should be present" do
@user.name = ""
assert_not @user.valid?
end
test "email should be present" do
@user.email = " "
assert_not @user.valid?
end
end
テストモデルにメールを追加。
class User < ApplicationRecord
validates :name, presence: true
validates :email, presence: true
end
モデルにヴァリデーション追加。
これで全部OKなはずなので
ec2-user:~/environment/sample_app (modeling-users) $ rails test
Running via Spring preloader in process 7596
Started with run options --seed 32141
9/9: [===================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.57296s
9 tests, 17 assertions, 0 failures, 0 errors, 0 skips
OKと。
テストもよくわからんし、テストモデルでかいてる
test "email should be present" do
@user.email = " "
assert_not @user.valid?
end
この辺の意味もわからん、空白がだめならヴァリデーションだけでよいのではないのか、プロゲート様。
ユーザーテストに追加。
test "name should not be too long" do
@user.name = "a" * 51
assert_not @user.valid?
end
test "email should not be too long" do
@user.email = "a" * 244 + "@example.com"
assert_not @user.valid?
end
もろもろ検証
ec2-user:~/environment/sample_app (modeling-users) $ rails console
Running via Spring preloader in process 7732
Loading development environment (Rails 5.1.6)
"a" * 51
=> "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
("a" * 51).length
=> 51
"a" * 244 + "@example.com"
=> "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@example.com"
("a" * 244 + "@example.com").length
=> 256
rails test
Traceback (most recent call last):
2: from (irb):5
1: from (irb):5:in `test'
ArgumentError (wrong number of arguments (given 0, expected 2..3))
ヴァリデーションを追加
validates :name, presence: true, length: { maximum: 50 }
validates :email, presence: true, length: { maximum: 255 }
で、テスト
rails test
Traceback (most recent call last):
2: from (irb):5
1: from (irb):5:intest' ArgumentError (wrong number of arguments (given 0, expected 2..3)) rails test Traceback (most recent call last): 3: from (irb):6 2: from (irb):6:in
rescue in irb_binding'
1: from (irb):6:in `test'
ArgumentError (wrong number of arguments (given 0, expected 2..3))
ec2-user:~/environment/sample_app (modeling-users) $ rails test
Running via Spring preloader in process 7905
Started with run options --seed 20099
ERROR["test_layout_links", SiteLayoutTest, 0.00558311000077083]
test_layout_links#SiteLayoutTest (0.01s)
NoMethodError: NoMethodError: undefined method validates' for #<Class:0x00007ff0f43201d0> Did you mean? validates validates! validate validators _validators app/models/user.rb:2:in
class:User'
app/models/user.rb:1:in `'
FAIL["test_email_should_not_be_too_long", UserTest, 0.4547210350001478]
test_email_should_not_be_too_long#UserTest (0.45s)
Expected true to be nil or false
test/models/user_test.rb:30:in `block in class:UserTest'
FAIL["test_name_should_be_present", UserTest, 0.4572972430005393]
test_name_should_be_present#UserTest (0.46s)
Expected true to be nil or false
test/models/user_test.rb:15:in `block in class:UserTest'
FAIL["test_name_should_not_be_too_long", UserTest, 0.45983286300088366]
test_name_should_not_be_too_long#UserTest (0.46s)
Expected true to be nil or false
test/models/user_test.rb:25:in `block in class:UserTest'
FAIL["test_email_should_be_present", UserTest, 0.46324869800082524]
test_email_should_be_present#UserTest (0.46s)
Expected true to be nil or false
test/models/user_test.rb:20:in `block in class:UserTest'
11/11: [=================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.47091s
11 tests, 14 assertions, 4 failures, 1 errors, 0 skips
なんか、サンドボックスから出てみたけど、そこでエラー。
まったく原因のわからないエラー。
validを理解せずに進めてきた弊害かなぁ。
このまま次いきます。
ユーザーテストにメールの条件追加
test "email validation should accept valid addresses" do
valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org
first.last@foo.jp alice+bob@baz.cn]
valid_addresses.each do |valid_address|
@user.email = valid_address
assert @user.valid?, "#{valid_address.inspect} should be valid"
end
end
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
で、テスト
ec2-user:~/environment/sample_app (modeling-users) $ rails test
Running via Spring preloader in process 8779
Started with run options --seed 29252
FAIL["test_email_validation_should_reject_invalid_addresses", UserTest, 0.5139025600001332]
test_email_validation_should_reject_invalid_addresses#UserTest (0.51s)
"user@example,com" should be invalid
test/models/user_test.rb:47:in block (2 levels) in <class:UserTest>' test/models/user_test.rb:45:in
each'
test/models/user_test.rb:45:in `block in class:UserTest'
13/13: [=================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.52426s
13 tests, 25 assertions, 1 failures, 0 errors, 0 skips
さっきより失敗が減ってる。謎。
モデルユーザーをメールをきちんとはじけるように正規表現とかつかって
構築しなおす。
class User < ApplicationRecord
validates :name, presence: true, length: { maximum: 50 }
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
ここでモデルのテスト
ec2-user:~/environment/sample_app (modeling-users) $ rails test:models
Started with run options --seed 9928
7/7: [===================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.05651s
7 tests, 15 assertions, 0 failures, 0 errors, 0 skips
一意性の検証
重要らしい。
メールアドレスの一意性を強制するために (ユーザー名として使うために)、validatesメソッドの:uniqueオプションを使います。ただしここで重大な警告があります。次の文面は流し読みせず、必ず注意深く読んでください。
まずは小さなテストから書いていきます。モデルのテストではこれまで、主にUser.newを使ってきました。このメソッドは単にメモリ上にRubyのオブジェクトを作るだけです。しかし、一意性のテストのためには、メモリ上だけではなく、実際にレコードをデータベースに登録する必要があります14。そのため、まずは重複したメールアドレスからテストしていきます (リスト 6.24)。
ユーザーテストに追記
test "email addresses should be unique" do
duplicate_user = @user.dup
@user.save
assert_not duplicate_user.valid?
end
dupは、同じ属性を持つデータを複製するためのメソッド
@userを保存した後では、複製されたユーザーのメールアドレスが既にデータベース内に存在するため、ユーザの作成は無効になる
モデルに追記
class User < ApplicationRecord
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+-.]+@[a-z\d-.]+.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: true
end
ここでアップケースも考えないとだめとのこと
test "email addresses should be unique" do
duplicate_user = @user.dup
duplicate_user.email = @user.email.upcase
@user.save
assert_not duplicate_user.valid?
end
検証
ec2-user:~/environment/sample_app (modeling-users) $ rails console --sandbox
Running via Spring preloader in process 9807
Loading development environment in sandbox (Rails 5.1.6)
Any modifications you make will be rolled back on exit
user = User.create(name: "Example User", email: "user@example.com")
(0.1ms) SAVEPOINT active_record_1
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ? [["email", "user@example.com"], ["LIMIT", 1]]
SQL (1.5ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["name", "Example User"], ["email", "user@example.com"], ["created_at", "2020-05-05 04:09:33.072845"], ["updated_at", "2020-05-05 04:09:33.072845"]]
(0.1ms) RELEASE SAVEPOINT active_record_1
=> #
user.email.upcase
=> "USER@EXAMPLE.COM"
duplicate_user = user.dup
=> #
duplicate_user.email = user.email.upcase
=> "USER@EXAMPLE.COM"
duplicate_user.valid?
User Exists (0.1ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ? [["email", "USER@EXAMPLE.COM"], ["LIMIT", 1]]
=> true
falseにならないといけないので
class User < ApplicationRecord
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+-.]+@[a-z\d-.]+.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
end
ヴァリデーションを追加
rueをcase_sensitive: falseに置き換えただけであることに注目
Railsはこの場合、:uniquenessをtrueと判断します
???
で、テスト
ec2-user:~/environment/sample_app (modeling-users) $ rails test
Running via Spring preloader in process 10009
Started with run options --seed 26197
14/14: [=================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.56773s
エラーなくなた
メールにインデックス機能をつけたい。
マイグレーションファイルを編集。
ec2-user:~/environment/sample_app (modeling-users) $ rails generate migration add_index_to_users_email
Running via Spring preloader in process 10192
invoke active_record
create db/migrate/20200505042250_add_index_to_users_email.rb
できたマイグレーションファイルを編集
class AddIndexToUsersEmail < ActiveRecord::Migration[5.0]
def change
add_index :users, :email, unique: true
end
end
で
ec2-user:~/environment/sample_app (modeling-users) $ rails db:migrate
== 20200505042250 AddIndexToUsersEmail: migrating =============================
== 20200505042250 AddIndexToUsersEmail: migrated (0.0000s) ====================
fixturesを空にします。
理由は意味不明。
いくつかのデータベースのアダプタが、常に大文字小文字を区別するインデックス を使っているとは限らない問題への対処です。例えば、Foo@ExAMPle.Comとfoo@example.comが別々の文字列だと解釈してしまうデータベースがありますが、私達のアプリケーションではこれらの文字列は同一であると解釈されるべきです。この問題を避けるために、今回は「データベースに保存される直前にすべての文字列を小文字に変換する」という対策を採ります。例えば"Foo@ExAMPle.CoM"という文字列が渡されたら、保存する直前に"foo@example.com"に変換してしまいます。これを実装するためにActive Recordのコールバック (callback) メソッドを利用
なるほど。
ユーザーモデルを編集
class User < ApplicationRecord
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+-.]+@[a-z\d-.]+.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
end
before_saveなるコールバックメソッドらしい。
ここで、プロゲートでも意味わかりにくい、selfがきた。
プロゲート的に、インスタンス変数とあったはず。
つまり、インスタンスごとに作成される変数、インスタンスごとに中身がかわる場合、
selfをつけましょうとか書いてた気がする、@の変数となにが違うの、という疑問。
チュートリアルでは
ちなみにこのselfは現在のユーザーを指します
とのこと。シンプルーーーー
やっとパスワード
セキュアなパスワードの設定のため、まずはマイグレーションファイルを編集
rails generate migration add_password_digest_to_users password_digest:string
class AddPasswordDigestToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :password_digest, :string
end
end
きちんと生成されてるので
ec2-user:~/environment/sample_app (modeling-users) $ rails db:migrate
== 20200505044314 AddPasswordDigestToUsers: migrating =========================
-- add_column(:users, :password_digest, :string)
-> 0.0022s
== 20200505044314 AddPasswordDigestToUsers: migrated (0.0027s) ================
パスワードもれてもいいようにジェムを追加
gem 'bcrypt', '3.1.12'
むしってた
has_secure_password
も、ユーザーモデルに追加
そしてインストール
ec2-user:~/environment/sample_app (modeling-users) $ bundle install
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java
.
Fetching gem metadata from https://rubygems.org/............
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Using rake 13.0.1
Using concurrent-ruby 1.1.6
Using i18n 1.8.2
Using minitest 5.10.3
Using thread_safe 0.3.6
Using tzinfo 1.2.7
Using activesupport 5.1.6
Using builder 3.2.4
Using erubi 1.9.0
Using mini_portile2 2.4.0
Using nokogiri 1.10.9
Using rails-dom-testing 2.0.3
Using crass 1.0.6
Using loofah 2.5.0
Using rails-html-sanitizer 1.3.0
Using actionview 5.1.6
Using rack 2.2.2
Using rack-test 1.1.0
Using actionpack 5.1.6
Using nio4r 2.5.2
Using websocket-extensions 0.1.4
Using websocket-driver 0.6.5
Using actioncable 5.1.6
Using globalid 0.4.2
Using activejob 5.1.6
Using mini_mime 1.0.2
Using mail 2.7.1
Using actionmailer 5.1.6
Using activemodel 5.1.6
Using arel 8.0.0
Using activerecord 5.1.6
Using ansi 1.5.0
Using execjs 2.7.0
Using autoprefixer-rails 9.7.6
Fetching bcrypt 3.1.12
Installing bcrypt 3.1.12 with native extensions
Using bindex 0.8.1
Using rb-fsevent 0.10.4
Using ffi 1.12.2
Using rb-inotify 0.10.1
Using sass-listen 4.0.0
Using sass 3.7.4
Using bootstrap-sass 3.3.7
Using bundler 1.17.3
Using byebug 9.0.6
Using coderay 1.1.2
Using coffee-script-source 1.12.2
Using coffee-script 2.4.1
Using method_source 1.0.0
Using thor 1.0.1
Using railties 5.1.6
Using coffee-rails 4.2.2
Using formatador 0.2.5
Using ruby_dep 1.5.0
Using listen 3.1.5
Using lumberjack 1.2.4
Using nenv 0.3.0
Using shellany 0.0.1
Using notiffany 0.1.3
Using pry 0.13.1
Using guard 2.16.2
Using guard-compat 1.2.1
Using guard-minitest 2.4.4
Using multi_json 1.14.1
Using jbuilder 2.7.0
Using jquery-rails 4.3.1
Using ruby-progressbar 1.10.1
Using minitest-reporters 1.1.14
Using puma 3.9.1
Using sprockets 3.7.2
Using sprockets-rails 3.2.1
Using rails 5.1.6
Using rails-controller-testing 1.0.2
Using tilt 2.0.10
Using sass-rails 5.0.6
Using spring 2.0.2
Using spring-watcher-listen 2.0.1
Using sqlite3 1.3.13
Using turbolinks-source 5.2.0
Using turbolinks 5.0.1
Using uglifier 3.2.0
Using web-console 3.5.1
Bundle complete! 23 Gemfile dependencies, 81 gems now installed.
Gems in the group production were not installed.
Use bundle info [gemname]
to see where a bundled gem is installed.
成功。
ここでテスト
ec2-user:~/environment/sample_app (modeling-users) $ rails test
Running via Spring preloader in process 12917
Started with run options --seed 48949
FAIL["test_should_be_valid", UserTest, 0.035689358999661636]
test_should_be_valid#UserTest (0.04s)
Expected false to be truthy.
test/models/user_test.rb:10:in `block in class:UserTest'
FAIL["test_email_validation_should_accept_valid_addresses", UserTest, 0.06069916099841066]
test_email_validation_should_accept_valid_addresses#UserTest (0.06s)
"user@example.com" should be valid
test/models/user_test.rb:38:in block (2 levels) in <class:UserTest>' test/models/user_test.rb:36:in
each'
test/models/user_test.rb:36:in `block in class:UserTest'
14/14: [=================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.49038s
14 tests, 26 assertions, 2 failures, 0 errors, 0 skips
エラーーーーー。
内容が前の未解決のやつと同じ。
もういや。
無視。
と、おもったらここはエラーでいいらしい。
require 'test_helper'
class UserTest < ActiveSupport::TestCase
def setup
@user = User.new(name: "Example User", email: "user@example.com",
password: "foobar", password_confirmation: "foobar")
end
test "should be valid" do
assert @user.valid?
end
test "name should be present" do
@user.name = ""
assert_not @user.valid?
end
test "email should be present" do
@user.email = " "
assert_not @user.valid?
end
test "name should not be too long" do
@user.name = "a" * 51
assert_not @user.valid?
end
test "email should not be too long" do
@user.email = "a" * 244 + "@example.com"
assert_not @user.valid?
end
test "email validation should accept valid addresses" do
valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org
first.last@foo.jp alice+bob@baz.cn]
valid_addresses.each do |valid_address|
@user.email = valid_address
assert @user.valid?, "#{valid_address.inspect} should be valid"
end
end
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
test "email addresses should be unique" do
duplicate_user = @user.dup
duplicate_user.email = @user.email.upcase
@user.save
assert_not duplicate_user.valid?
end
end
password: "foobar", password_confirmation: "foobar"を追加する。
フーバーって誰。
で、テスト
ec2-user:~/environment/sample_app (modeling-users) $ rails test
Running via Spring preloader in process 13127
Started with run options --seed 55784
14/14: [=================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.54161s
14 tests, 30 assertions, 0 failures, 0 errors, 0 skips
エラーがなくなるという罠。
パスワードの最小文字数にかんする追加を
ユーザーテストに。
require 'test_helper'
class UserTest < ActiveSupport::TestCase
def setup
@user = User.new(name: "Example User", email: "user@example.com",
password: "foobar", password_confirmation: "foobar")
end
test "should be valid" do
assert @user.valid?
end
test "name should be present" do
@user.name = ""
assert_not @user.valid?
end
test "email should be present" do
@user.email = " "
assert_not @user.valid?
end
test "name should not be too long" do
@user.name = "a" * 51
assert_not @user.valid?
end
test "email should not be too long" do
@user.email = "a" * 244 + "@example.com"
assert_not @user.valid?
end
test "email validation should accept valid addresses" do
valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org
first.last@foo.jp alice+bob@baz.cn]
valid_addresses.each do |valid_address|
@user.email = valid_address
assert @user.valid?, "#{valid_address.inspect} should be valid"
end
end
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
test "email addresses should be unique" do
duplicate_user = @user.dup
duplicate_user.email = @user.email.upcase
@user.save
assert_not duplicate_user.valid?
end
test "password should be present (nonblank)" do
@user.password = @user.password_confirmation = " " * 6
assert_not @user.valid?
end
test "password should have a minimum length" do
@user.password = @user.password_confirmation = "a" * 5
assert_not @user.valid?
end
end
下の二つが追記分。
ミニマムのバリデーションも追加
class User < ApplicationRecord
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+-.]+@[a-z\d-.]+.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
end
モデルのテスト
ec2-user:~/environment/sample_app (modeling-users) $ rails test:models
Started with run options --seed 43058
10/10: [=================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.11680s
10 tests, 18 assertions, 0 failures, 0 errors, 0 skips
一人実際にDBに登録しましょう、サンドボックスはつかいません
ec2-user:~/environment/sample_app (modeling-users) $ rails console
Running via Spring preloader in process 13387
Loading development environment (Rails 5.1.6)
User.create(name: "Michael Hartl", email: "mhartl@example.com",
?> password: "foobar", password_confirmation: "foobar")
(0.1ms) begin transaction
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) LIMIT ? [["email", "mhartl@example.com"], ["LIMIT", 1]]
SQL (1.7ms) INSERT INTO "users" ("name", "email", "created_at", "updated_at", "password_digest") VALUES (?, ?, ?, ?, ?) [["name", "Michael Hartl"], ["email", "mhartl@example.com"], ["created_at", "2020-05-05 05:02:56.508168"], ["updated_at", "2020-05-05 05:02:56.508168"], ["password_digest", "$2a$10$zjzfkvsimhFwLB0RuXRQxOIOZSQTyUUyPYabuX7sU37Xjk3Jx6HwG"]]
(6.5ms) commit transaction
=> #
で、登録できたかをチェック。
登録できてなさそうだったのでなんかガチャガチャしてしまった。
結果、DLしたDB Browser (SQLite)の使い方の問題。
DLしたファイルを開いたら、左上の小さいテーブルのところで
usersを選択してあげないといけない。
ガチャガチャしたのでここのコードはのせません。
さて、最後。
テストしてgitしてherokuにデプロイ。
ec2-user:~/environment/sample_app (modeling-users) $ rails test
Running via Spring preloader in process 13946
Started with run options --seed 20052
16/16: [=================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.49156s
16 tests, 32 assertions, 0 failures, 0 errors, 0 skips
ec2-user:~/environment/sample_app (modeling-users) $ git add -A
ec2-user:~/environment/sample_app (modeling-users) $ git commit -m "Make a basic User model (including secure passwords)"
[modeling-users fecaf31] Make a basic User model (including secure passwords)
9 files changed, 127 insertions(+)
create mode 100644 app/models/user.rb
create mode 100644 db/migrate/20200505013551_create_users.rb
create mode 100644 db/migrate/20200505042250_add_index_to_users_email.rb
create mode 100644 db/migrate/20200505044314_add_password_digest_to_users.rb
create mode 100644 db/schema.rb
create mode 100644 test/fixtures/users.yml
create mode 100644 test/models/user_test.rb
ec2-user:~/environment/sample_app (modeling-users) $ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
ec2-user:~/environment/sample_app (master) $ git merge modeling-users
Updating 4564f26..fecaf31
Fast-forward
Gemfile | 1 +
Gemfile.lock | 2 ++
app/models/user.rb | 10 ++++++++++
db/migrate/20200505013551_create_users.rb | 10 ++++++++++
db/migrate/20200505042250_add_index_to_users_email.rb | 5 +++++
db/migrate/20200505044314_add_password_digest_to_users.rb | 5 +++++
db/schema.rb | 23 +++++++++++++++++++++++
test/fixtures/users.yml | 1 +
test/models/user_test.rb | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 127 insertions(+)
create mode 100644 app/models/user.rb
create mode 100644 db/migrate/20200505013551_create_users.rb
create mode 100644 db/migrate/20200505042250_add_index_to_users_email.rb
create mode 100644 db/migrate/20200505044314_add_password_digest_to_users.rb
create mode 100644 db/schema.rb
create mode 100644 test/fixtures/users.yml
create mode 100644 test/models/user_test.rb
ec2-user:~/environment/sample_app (master) $ git push
Counting objects: 18, done.
Compressing objects: 100% (18/18), done.
Writing objects: 100% (18/18), 3.01 KiB | 615.00 KiB/s, done.
Total 18 (delta 5), reused 0 (delta 0)
To bitbucket.org:fumiaki1011/sample_app.git
4564f26..fecaf31 master -> master
ec2-user:~/environment/sample_app (master) $ rails test
Running via Spring preloader in process 14119
Started with run options --seed 62677
16/16: [=================================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.48898s
16 tests, 32 assertions, 0 failures, 0 errors, 0 skips
ec2-user:~/environment/sample_app (master) $ git push heroku
Counting objects: 18, done.
Compressing objects: 100% (18/18), done.
Writing objects: 100% (18/18), 3.01 KiB | 615.00 KiB/s, done.
Total 18 (delta 5), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Ruby app detected
remote: -----> Installing bundler 1.17.3
remote: -----> Removing BUNDLED WITH version in the Gemfile.lock
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.6.6
remote: -----> Installing dependencies using bundler 1.17.3
remote: Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
remote: The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java
.
remote: Fetching gem metadata from https://rubygems.org/............
remote: Using rake 13.0.1
remote: Using concurrent-ruby 1.1.6
remote: Using minitest 5.10.3
remote: Using thread_safe 0.3.6
remote: Using builder 3.2.4
remote: Using erubi 1.9.0
remote: Using mini_portile2 2.4.0
remote: Using crass 1.0.6
remote: Using rack 2.2.2
remote: Using nio4r 2.5.2
remote: Using websocket-extensions 0.1.4
remote: Using mini_mime 1.0.2
remote: Using arel 8.0.0
remote: Using execjs 2.7.0
remote: Fetching bcrypt 3.1.12
remote: Using rb-fsevent 0.10.4
remote: Using ffi 1.12.2
remote: Using bundler 1.17.3
remote: Using coffee-script-source 1.12.2
remote: Using method_source 1.0.0
remote: Using thor 1.0.1
remote: Using multi_json 1.14.1
remote: Using pg 0.20.0
remote: Using puma 3.9.1
remote: Using tilt 2.0.10
remote: Using turbolinks-source 5.2.0
remote: Using i18n 1.8.2
remote: Using tzinfo 1.2.7
remote: Using nokogiri 1.10.9
remote: Using rack-test 1.1.0
remote: Using websocket-driver 0.6.5
remote: Using mail 2.7.1
remote: Using autoprefixer-rails 9.7.6
remote: Using sprockets 3.7.2
remote: Using uglifier 3.2.0
remote: Using activesupport 5.1.6
remote: Using loofah 2.5.0
remote: Using rb-inotify 0.10.1
remote: Using coffee-script 2.4.1
remote: Using turbolinks 5.0.1
remote: Using rails-dom-testing 2.0.3
remote: Using rails-html-sanitizer 1.3.0
remote: Using activemodel 5.1.6
remote: Using jbuilder 2.7.0
remote: Using actionview 5.1.6
remote: Using globalid 0.4.2
remote: Using actionpack 5.1.6
remote: Using activerecord 5.1.6
remote: Using sass-listen 4.0.0
remote: Using actioncable 5.1.6
remote: Using sass 3.7.4
remote: Using railties 5.1.6
remote: Using sprockets-rails 3.2.1
remote: Using activejob 5.1.6
remote: Using actionmailer 5.1.6
remote: Using bootstrap-sass 3.3.7
remote: Using coffee-rails 4.2.2
remote: Using jquery-rails 4.3.1
remote: Using sass-rails 5.0.6
remote: Using rails 5.1.6
remote: Installing bcrypt 3.1.12 with native extensions
remote: Bundle complete! 23 Gemfile dependencies, 60 gems now installed.
remote: Gems in the groups development and test were not installed.
remote: Bundled gems are installed into ./vendor/bundle
remote: Bundle completed (5.71s)
remote: Cleaning up the bundler cache.
remote: The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java
.
remote: -----> Installing node-v10.15.3-linux-x64
remote: -----> Detecting rake tasks
remote: -----> Preparing app for Rails asset pipeline
remote: Running: rake assets:precompile
remote: Yarn executable was not detected in the system.
remote: Download Yarn at https://yarnpkg.com/en/docs/install
remote: Asset precompilation completed (1.90s)
remote: Cleaning assets
remote: Running: rake assets:clean
remote: -----> Detecting rails configuration
remote:
remote: ###### WARNING:
remote:
remote: You have not declared a Ruby version in your Gemfile.
remote: To set your Ruby version add this line to your Gemfile:
remote: ruby '2.6.6'
remote: # See https://devcenter.heroku.com/articles/ruby-versions for more information.
remote:
remote: ###### WARNING:
remote:
remote: No Procfile detected, using the default web server.
remote: We recommend explicitly declaring how to boot your server process via a Procfile.
remote: https://devcenter.heroku.com/articles/ruby-default-web-server
remote:
remote:
remote: -----> Discovering process types
remote: Procfile declares types -> (none)
remote: Default types for buildpack -> console, rake, web
remote:
remote: -----> Compressing...
remote: Done: 64.6M
remote: -----> Launching...
remote: Released v10
remote: https://stark-reaches-53742.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/stark-reaches-53742.git
4564f26..fecaf31 master -> master
ec2-user:~/environment/sample_app (master) $ heroku run rails db:migrate
bash: heroku: command not found
ec2-user:~/environment/sample_app (master) $ source <(curl -sL https://cdn.learnenough.com/heroku_install)
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 27.4M 100 27.4M 0 0 71.7M 0 --:--:-- --:--:-- --:--:-- 71.6M
mv: cannot move ‘heroku’ to ‘/usr/local/heroku’: Directory not empty
ec2-user:~/environment/sample_app (master) $ heroku run rails db:migrate
Running rails db:migrate on ⬢ stark-reaches-53742... up, run.9886 (Free)
D, [2020-05-05T05:26:47.370050 #4] DEBUG -- : (133.9ms) CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY)
D, [2020-05-05T05:26:47.417051 #4] DEBUG -- : (43.2ms) CREATE TABLE "ar_internal_metadata" ("key" character varying NOT NULL PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
D, [2020-05-05T05:26:47.419835 #4] DEBUG -- : (1.2ms) SELECT pg_try_advisory_lock(2019793553588309940)
D, [2020-05-05T05:26:47.450980 #4] DEBUG -- : (1.6ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
I, [2020-05-05T05:26:47.452130 #4] INFO -- : Migrating to CreateUsers (20200505013551)
D, [2020-05-05T05:26:47.454776 #4] DEBUG -- : (1.0ms) BEGIN
== 20200505013551 CreateUsers: migrating ======================================
-- create_table(:users)
D, [2020-05-05T05:26:47.470289 #4] DEBUG -- : (14.9ms) CREATE TABLE "users" ("id" bigserial primary key, "name" character varying, "email" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
-> 0.0154s
== 20200505013551 CreateUsers: migrated (0.0155s) =============================
D, [2020-05-05T05:26:47.476217 #4] DEBUG -- : SQL (1.5ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version" [["version", "20200505013551"]]
D, [2020-05-05T05:26:47.500906 #4] DEBUG -- : (24.3ms) COMMIT
I, [2020-05-05T05:26:47.501073 #4] INFO -- : Migrating to AddIndexToUsersEmail (20200505042250)
D, [2020-05-05T05:26:47.502896 #4] DEBUG -- : (1.3ms) BEGIN
== 20200505042250 AddIndexToUsersEmail: migrating =============================
-- add_index(:users, :email, {:unique=>true})
D, [2020-05-05T05:26:47.515012 #4] DEBUG -- : (5.0ms) CREATE UNIQUE INDEX "index_users_on_email" ON "users" ("email")
-> 0.0121s
== 20200505042250 AddIndexToUsersEmail: migrated (0.0122s) ====================
D, [2020-05-05T05:26:47.517247 #4] DEBUG -- : SQL (1.3ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version" [["version", "20200505042250"]]
D, [2020-05-05T05:26:47.526022 #4] DEBUG -- : (8.5ms) COMMIT
I, [2020-05-05T05:26:47.526133 #4] INFO -- : Migrating to AddPasswordDigestToUsers (20200505044314)
D, [2020-05-05T05:26:47.527739 #4] DEBUG -- : (1.1ms) BEGIN
== 20200505044314 AddPasswordDigestToUsers: migrating =========================
-- add_column(:users, :password_digest, :string)
D, [2020-05-05T05:26:47.530182 #4] DEBUG -- : (2.0ms) ALTER TABLE "users" ADD "password_digest" character varying
-> 0.0023s
== 20200505044314 AddPasswordDigestToUsers: migrated (0.0024s) ================
D, [2020-05-05T05:26:47.532470 #4] DEBUG -- : SQL (1.6ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version" [["version", "20200505044314"]]
D, [2020-05-05T05:26:47.539285 #4] DEBUG -- : (6.6ms) COMMIT
D, [2020-05-05T05:26:47.547332 #4] DEBUG -- : ActiveRecord::InternalMetadata Load (1.4ms) SELECT "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2 [["key", "environment"], ["LIMIT", 1]]
D, [2020-05-05T05:26:47.554745 #4] DEBUG -- : (1.1ms) BEGIN
D, [2020-05-05T05:26:47.557140 #4] DEBUG -- : SQL (1.5ms) INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key" [["key", "environment"], ["value", "production"], ["created_at", "2020-05-05 05:26:47.554994"], ["updated_at", "2020-05-05 05:26:47.554994"]]
D, [2020-05-05T05:26:47.566883 #4] DEBUG -- : (9.5ms) COMMIT
D, [2020-05-05T05:26:47.568269 #4] DEBUG -- : (1.2ms) SELECT pg_advisory_unlock(2019793553588309940)
ec2-user:~/environment/sample_app (master) $ heroku run rails console --sandbox
Running rails console --sandbox on ⬢ stark-reaches-53742... up, run.8313 (Free)
D, [2020-05-05T05:27:51.036693 #4] DEBUG -- : (1.0ms) BEGIN
Loading production environment in sandbox (Rails 5.1.6)
Any modifications you make will be rolled back on exit
irb(main):001:0> User.create(name: "Michael Hartl", email: "michael@example.com",
irb(main):002:1* ?> password: "foobar", password_confirmation: "foobar")
Traceback (most recent call last):
SyntaxError ((irb):2: syntax error, unexpected tIDENTIFIER, expecting =>)
?> password: "foobar", password_confirma...
^~~~~~~~
irb(main):003:0>
D, [2020-05-05T05:29:27.681027 #4] DEBUG -- : (1.5ms) ROLLBACK
ec2-user:~/environment/sample_app (master) $
なんか最後の本番環境でのチェックができてないというかいみわからんかったけどまあよし 。
6章ハードやったー
まじハード。
これ書くのもハード。意味あんのかな。