Tambourine作業メモ

主にスキル習得のためにやった作業のメモ。他人には基本的に無用のものです。

Rails チュートリアルをやってみる(6) 2.3.4〜2.4 DBを使うアプリをHerokuにデプロイ

2.3.4 から読む。

ApplicationRecordとか、ApplicationControllerって昔からあったっけ? なんか昔はActiveRecord::Baseを直接継承していたような気もするけど、気のせいのような気もする。ここの演習は、特にどうということもないので、パス。

2.3.5 でデプロイ。そうか、デプロイした先はSQLiteじゃないんだよな。

> git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   config/routes.rb

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    app/assets/javascripts/microposts.coffee
    app/assets/javascripts/users.coffee
(中略)
    test/system/users_test.rb

no changes added to commit (use "git add" and/or "git commit -a")
> git add --all
> git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   app/assets/javascripts/microposts.coffee
    new file:   app/assets/javascripts/users.coffee
(中略)
    new file:   test/system/users_test.rb

> git commit -m "Fnish toy app"
[master 6acfa6f] Fnish toy app
 39 files changed, 629 insertions(+)
 create mode 100644 app/assets/javascripts/microposts.coffee
 create mode 100644 app/assets/javascripts/users.coffee
(中略)
 create mode 100644 test/system/users_test.rb
> git push heroku
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream heroku master

あれ、お手本通りなのに・・・まあ、確かに.git/configが更新されるようなことしてないか。 わかったようでわかってないなあ・・・この辺りも。

> git push heroku master
Counting objects: 58, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (55/55), done.
Writing objects: 100% (58/58), 8.88 KiB | 908.00 KiB/s, done.
Total 58 (delta 10), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> Ruby app detected
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.4.5
remote: -----> Installing dependencies using bundler 1.15.2
remote:        Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
remote:        Warning: the running version of Bundler (1.15.2) is older than the version that created the lockfile (1.17.1). We suggest you upgrade to the latest version of Bundler by running `gem install bundler`.
remote:        Fetching gem metadata from https://rubygems.org/.........
remote:        Fetching version metadata from https://rubygems.org/..
remote:        Fetching dependency metadata from https://rubygems.org/.
remote:        Using rake 12.3.1
(中略)
remote:        Using rails 5.1.6
remote:        Using sass-rails 5.0.6
remote:        Bundle complete! 15 Gemfile dependencies, 57 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 (2.99s)
remote:        Cleaning up the bundler cache.
remote:        Warning: the running version of Bundler (1.15.2) is older than the version that created the lockfile (1.17.1). We suggest you upgrade to the latest version of Bundler by running `gem install bundler`.
remote:        The latest bundler is 2.0.0.pre.1, but you are currently running 1.15.2.
remote:        To update, run `gem install bundler --pre`
remote: -----> Installing node-v8.10.0-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:        I, [2018-11-21T23:54:30.804003 #414]  INFO -- : Writing /tmp/build_8ff5bb0b6a68b700c5ccd050ae96d2ca/public/assets/application-7441e90aaeea08ce2c76b4123cab0e756e62755c6fc9732dae8cff9bdd6bdd5d.js
remote:        I, [2018-11-21T23:54:30.814388 #414]  INFO -- : Writing /tmp/build_8ff5bb0b6a68b700c5ccd050ae96d2ca/public/assets/application-7441e90aaeea08ce2c76b4123cab0e756e62755c6fc9732dae8cff9bdd6bdd5d.js.gz
remote:        I, [2018-11-21T23:54:30.854991 #414]  INFO -- : Writing /tmp/build_8ff5bb0b6a68b700c5ccd050ae96d2ca/public/assets/application-35729bfbaf9967f119234595ed222f7ab14859f304ab0acc5451afb387f637fa.css
remote:        I, [2018-11-21T23:54:30.855157 #414]  INFO -- : Writing /tmp/build_8ff5bb0b6a68b700c5ccd050ae96d2ca/public/assets/application-35729bfbaf9967f119234595ed222f7ab14859f304ab0acc5451afb387f637fa.css.gz
remote:        Asset precompilation completed (2.94s)
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.4.5'
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: 41.1M
remote: -----> Launching...
remote:        Released v7
remote:        https://sleepy-tundra-20972.herokuapp.com/ deployed to Heroku
remote: 
remote: Verifying deploy... done.
To https://git.heroku.com/sleepy-tundra-20972.git
   b08b557..6acfa6f  master -> master

WARNINGが2つ出てる。一つは、Rubyのバージョンを指定してねということ。 もう1つはProcfileを作ってねということ。Procfileってのが何かは知らないけど、Webサーバの設定みたいね、書きっぷりに依ると。

そして、サーバでもdb:migrateを動かす。

> heroku run rails db:migrate
Running rails db:migrate on ⬢ sleepy-tundra-20972... up, run.4540 (Free)
D, [2018-11-22T00:30:22.087474 #4] DEBUG -- :    (2478.1ms)  CREATE TABLE "schema_migrations" ("version" character varying NOT NULL PRIMARY KEY)
D, [2018-11-22T00:30:22.296513 #4] DEBUG -- :    (192.4ms)  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, [2018-11-22T00:30:22.300757 #4] DEBUG -- :    (2.4ms)  SELECT pg_try_advisory_lock(5716602264330689130)
D, [2018-11-22T00:30:22.890142 #4] DEBUG -- :    (3.2ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
I, [2018-11-22T00:30:22.900519 #4]  INFO -- : Migrating to CreateUsers (20181121083708)
D, [2018-11-22T00:30:22.909231 #4] DEBUG -- :    (6.2ms)  BEGIN
== 20181121083708 CreateUsers: migrating ======================================
-- create_table(:users)
D, [2018-11-22T00:30:23.199084 #4] DEBUG -- :    (288.6ms)  CREATE TABLE "users" ("id" bigserial primary key, "name" character varying, "email" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
   -> 0.2895s
== 20181121083708 CreateUsers: migrated (0.2898s) =============================

D, [2018-11-22T00:30:23.211820 #4] DEBUG -- :   SQL (4.5ms)  INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version"  [["version", "20181121083708"]]
D, [2018-11-22T00:30:23.220505 #4] DEBUG -- :    (8.1ms)  COMMIT
I, [2018-11-22T00:30:23.220809 #4]  INFO -- : Migrating to CreateMicroposts (20181121142643)
D, [2018-11-22T00:30:23.222889 #4] DEBUG -- :    (1.4ms)  BEGIN
== 20181121142643 CreateMicroposts: migrating =================================
-- create_table(:microposts)
D, [2018-11-22T00:30:23.353304 #4] DEBUG -- :    (129.3ms)  CREATE TABLE "microposts" ("id" bigserial primary key, "content" text, "user_id" integer, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
   -> 0.1302s
== 20181121142643 CreateMicroposts: migrated (0.1306s) ========================

D, [2018-11-22T00:30:23.356405 #4] DEBUG -- :   SQL (1.3ms)  INSERT INTO "schema_migrations" ("version") VALUES ($1) RETURNING "version"  [["version", "20181121142643"]]
D, [2018-11-22T00:30:23.361482 #4] DEBUG -- :    (4.5ms)  COMMIT
D, [2018-11-22T00:30:23.376553 #4] DEBUG -- :   ActiveRecord::InternalMetadata Load (4.0ms)  SELECT  "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2  [["key", "environment"], ["LIMIT", 1]]
D, [2018-11-22T00:30:23.392515 #4] DEBUG -- :    (6.6ms)  BEGIN
D, [2018-11-22T00:30:23.400575 #4] DEBUG -- :   SQL (6.6ms)  INSERT INTO "ar_internal_metadata" ("key", "value", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "key"  [["key", "environment"], ["value", "production"], ["created_at", "2018-11-22 00:30:23.393033"], ["updated_at", "2018-11-22 00:30:23.393033"]]
D, [2018-11-22T00:30:23.405696 #4] DEBUG -- :    (4.6ms)  COMMIT
D, [2018-11-22T00:30:23.412499 #4] DEBUG -- :    (6.4ms)  SELECT pg_advisory_unlock(5716602264330689130)

すげー。なんでDBに接続できてるのか全然わかんないけど、DBできとる・・・。

さて、動いたので早速ユーザーを作ってみよう。新規登録をすると・・・

f:id:Tambourine:20181122093749p:plain

落ちる。これはたぶんUser.microposts.firstがnilを返すためで、チュートリアルにも演習の部分は戻してねと書いてある。

しかし、ログはどうやって見るんだ・・・。herokuコマンドのヘルプを見ると、logsと言うコマンドがある。

> heroku logs
2018-11-22T00:34:44.792223+00:00 heroku[router]: at=info method=GET path="/users/1" host=sleepy-tundra-20972.herokuapp.com request_id=07f66d18-b44c-4056-893f-7af6583dfd99 fwd="163.131.137.128" dyno=web.1 connect=1ms service=41ms status=500 bytes=1827 protocol=https
2018-11-22T00:34:44.752424+00:00 app[web.1]: I, [2018-11-22T00:34:44.752292 #4]  INFO -- : [07f66d18-b44c-4056-893f-7af6583dfd99] Started GET "/users/1" for 163.131.137.128 at 2018-11-22 00:34:44 +0000
2018-11-22T00:34:44.753370+00:00 app[web.1]: I, [2018-11-22T00:34:44.753294 #4]  INFO -- : [07f66d18-b44c-4056-893f-7af6583dfd99] Processing by UsersController#show as HTML
2018-11-22T00:34:44.753448+00:00 app[web.1]: I, [2018-11-22T00:34:44.753383 #4]  INFO -- : [07f66d18-b44c-4056-893f-7af6583dfd99]   Parameters: {"id"=>"1"}
2018-11-22T00:34:44.761960+00:00 app[web.1]: D, [2018-11-22T00:34:44.761881 #4] DEBUG -- : [07f66d18-b44c-4056-893f-7af6583dfd99]   User Load (1.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
2018-11-22T00:34:44.763717+00:00 app[web.1]: I, [2018-11-22T00:34:44.763660 #4]  INFO -- : [07f66d18-b44c-4056-893f-7af6583dfd99]   Rendering users/show.html.erb within layouts/application
2018-11-22T00:34:44.786902+00:00 app[web.1]: D, [2018-11-22T00:34:44.786783 #4] DEBUG -- : [07f66d18-b44c-4056-893f-7af6583dfd99]   Micropost Load (6.8ms)  SELECT  "microposts".* FROM "microposts" WHERE "microposts"."user_id" = $1 ORDER BY "microposts"."id" ASC LIMIT $2  [["user_id", 1], ["LIMIT", 1]]
2018-11-22T00:34:44.789702+00:00 app[web.1]: I, [2018-11-22T00:34:44.789635 #4]  INFO -- : [07f66d18-b44c-4056-893f-7af6583dfd99]   Rendered users/show.html.erb within layouts/application (25.8ms)
2018-11-22T00:34:44.789984+00:00 app[web.1]: I, [2018-11-22T00:34:44.789918 #4]  INFO -- : [07f66d18-b44c-4056-893f-7af6583dfd99] Completed 500 Internal Server Error in 36ms (ActiveRecord: 21.4ms)
2018-11-22T00:34:44.790936+00:00 app[web.1]: F, [2018-11-22T00:34:44.790843 #4] FATAL -- : [07f66d18-b44c-4056-893f-7af6583dfd99]
2018-11-22T00:34:44.790997+00:00 app[web.1]: F, [2018-11-22T00:34:44.790936 #4] FATAL -- : [07f66d18-b44c-4056-893f-7af6583dfd99] ActionView::Template::Error (undefined method `content' for nil:NilClass):
2018-11-22T00:34:44.791148+00:00 app[web.1]: F, [2018-11-22T00:34:44.791090 #4] FATAL -- : [07f66d18-b44c-4056-893f-7af6583dfd99]     12:
2018-11-22T00:34:44.791151+00:00 app[web.1]: [07f66d18-b44c-4056-893f-7af6583dfd99]     13: <p>
2018-11-22T00:34:44.791153+00:00 app[web.1]: [07f66d18-b44c-4056-893f-7af6583dfd99]     14:   <strong>Content:</strong>
2018-11-22T00:34:44.791155+00:00 app[web.1]: [07f66d18-b44c-4056-893f-7af6583dfd99]     15:   <%= @user.microposts.first.content %>
2018-11-22T00:34:44.791157+00:00 app[web.1]: [07f66d18-b44c-4056-893f-7af6583dfd99]     16: </p>
2018-11-22T00:34:44.791159+00:00 app[web.1]: [07f66d18-b44c-4056-893f-7af6583dfd99]     17:
2018-11-22T00:34:44.791160+00:00 app[web.1]: [07f66d18-b44c-4056-893f-7af6583dfd99]     18: <%= link_to 'Edit', edit_user_path(@user) %> |
2018-11-22T00:34:44.791209+00:00 app[web.1]: F, [2018-11-22T00:34:44.791142 #4] FATAL -- : [07f66d18-b44c-4056-893f-7af6583dfd99]
2018-11-22T00:34:44.791264+00:00 app[web.1]: F, [2018-11-22T00:34:44.791209 #4] FATAL -- : [07f66d18-b44c-4056-893f-7af6583dfd99] app/views/users/show.html.erb:15:in `_app_views_users_show_html_erb__2495298628157736775_47439747321080'

親切だ。"undefined method `content' for nil:NilClass"となっているのでここで落ちているわけ。 チュートリアルは戻せと言っているけど、直しちゃおう。

app/views/users/show.html.erbを

<%= @user.microposts.first.content %>

から

 <%= @user.microposts.first&.content or "No post" %>

にするだけで良いはず。ああ、ラクだなあ、Rubyは。修正してデプロイ。

f:id:Tambourine:20181122095620p:plain

さて、DBの中を見るにはどうしたら良いんだ・・・heroku psqlってのがあるぞ?

> heroku psql
--> Connecting to postgresql-metric-47854
 ▸    The local psql command could not be located. For help installing psql, see https://devcenter.heroku.com/articles/heroku-postgresql#local-setup

はうっ。なるほど。ローカルにPostgreSQLをインストールされてないとダメなのか。

> brew install postgresql
==> Installing dependencies for postgresql: icu4c
==> Installing postgresql dependency: icu4c
==> Downloading https://homebrew.bintray.com/bottles/icu4c-62.1.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring icu4c-62.1.high_sierra.bottle.tar.gz
==> Caveats
icu4c is keg-only, which means it was not symlinked into /usr/local,
because macOS provides libicucore.dylib (but nothing else).

If you need to have icu4c first in your PATH run:
  echo 'set -g fish_user_paths "/usr/local/opt/icu4c/bin" $fish_user_paths' >> ~/.config/fish/config.fish
  echo 'set -g fish_user_paths "/usr/local/opt/icu4c/sbin" $fish_user_paths' >> ~/.config/fish/config.fish

For compilers to find icu4c you may need to set:
  set -gx LDFLAGS "-L/usr/local/opt/icu4c/lib"
  set -gx CPPFLAGS "-I/usr/local/opt/icu4c/include"

For pkg-config to find icu4c you may need to set:
  set -gx PKG_CONFIG_PATH "/usr/local/opt/icu4c/lib/pkgconfig"

==> Summary
🍺  /usr/local/Cellar/icu4c/62.1: 250 files, 67.3MB
==> Installing postgresql
==> Downloading https://homebrew.bintray.com/bottles/postgresql-10.5.high_sierra.bottle.1.tar.gz
######################################################################## 100.0%
==> Pouring postgresql-10.5.high_sierra.bottle.1.tar.gz
==> /usr/local/Cellar/postgresql/10.5/bin/initdb /usr/local/var/postgres
==> Caveats
To migrate existing data from a previous major version of PostgreSQL run:
  brew postgresql-upgrade-database

To have launchd start postgresql now and restart at login:
  brew services start postgresql
Or, if you don't want/need a background service you can just run:
  pg_ctl -D /usr/local/var/postgres start
==> Summary
🍺  /usr/local/Cellar/postgresql/10.5: 3,395 files, 39.6MB
==> Caveats
==> icu4c
icu4c is keg-only, which means it was not symlinked into /usr/local,
because macOS provides libicucore.dylib (but nothing else).

If you need to have icu4c first in your PATH run:
  echo 'set -g fish_user_paths "/usr/local/opt/icu4c/bin" $fish_user_paths' >> ~/.config/fish/config.fish
  echo 'set -g fish_user_paths "/usr/local/opt/icu4c/sbin" $fish_user_paths' >> ~/.config/fish/config.fish

For compilers to find icu4c you may need to set:
  set -gx LDFLAGS "-L/usr/local/opt/icu4c/lib"
  set -gx CPPFLAGS "-I/usr/local/opt/icu4c/include"

For pkg-config to find icu4c you may need to set:
  set -gx PKG_CONFIG_PATH "/usr/local/opt/icu4c/lib/pkgconfig"

==> postgresql
To migrate existing data from a previous major version of PostgreSQL run:
  brew postgresql-upgrade-database

To have launchd start postgresql now and restart at login:
  brew services start postgresql
Or, if you don't want/need a background service you can just run:
  pg_ctl -D /usr/local/var/postgres start

リトライ

> heroku psql
--> Connecting to postgresql-metric-47854
psql (10.5, server 10.6 (Ubuntu 10.6-1.pgdg14.04+1))
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

sleepy-tundra-20972::DATABASE=> SELECT * FROM users;
 id |        name        |   email   |         created_at         |         updated_at         
----+--------------------+-----------+----------------------------+----------------------------
  1 | ルイス・ハミルトン | lh@ex.com | 2018-11-22 00:34:44.387942 | 2018-11-22 00:34:44.387942
(1 row)

おー、なんか扱えそうな気がしてきたよ。

というところで、2章は終わり。うーん、先は長い。