Railsで「Hello」と表示する: 小林研 Rails Tips (52)

はじめに

Rails Tips の 52 回目です。昨日、サーバを立ち上げようとしたらデータベースのエラーになってしまいました。ひとまずデータベースを作成しましょう。

Rails をはじめよう - Railsガイド

データベースの作成

homebrew でインストールした postgresql の/opt/homebrew/var/postgresql@16/pg_hba.conf を確認したところ、local からのアクセスは trust になっていました。development で実行している限りはパスワードなどの設定は必要ないです。

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 trust

実際、config/database.yml を確認してみると、特にパスワードなどの設定も書かれていません。

default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # https://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: hkob_blog_development

  # The specified database role being used to connect to PostgreSQL.
  # To create additional roles in PostgreSQL see `$ createuser --help`.
  # When left blank, PostgreSQL will use the default role. This is
  # the same name as the operating system user running Rails.
  #username: hkob_blog

  # The password associated with the PostgreSQL role (username).
  #password:

  # Connect on a TCP socket. Omitted by default since the client uses a
  # domain socket that doesn't need configuration. Windows does not have
  # domain sockets, so uncomment these lines.
  #host: localhost

この状態で、db:create してみましょう。

$ bin/rails db:create
Created database 'hkob_blog_development'
Created database 'hkob_blog_test'

無事に成功できています。再度 bin/rails s をすると今度は正しく Rails の画面が表示されました。

RailsTop

generator の設定

コントローラを作成する前に generator の設定が必要でした。config/initializers の下に generators.rb を作成し、以下の内容を記述します。test_framework を rspec に接停止、fixtures、request_spec のみ true にします。

Rails.application.config.generators do |g|
  g.test_framework :rspec
  g.stylesheets false
  g.javascripts false
  g.helper false
  g.channel assets: false
  g.fixtures true
  g.view_specs false
  g.routing_specs false
  g.controller_specs false
  g.request_specs true
  g.helper_specs false
end

4.2 Railsで「Hello」と表示する

そろそろ、Rails ガイドの内容に戻ります。最初に config/routes.rb/articles のルーティングを設定します。これは /articles というパスに get でアクセスした場合には、articles_controllerindex アクションを呼び出すという意味です。

  get "/articles", to: "articles#index"

このためには articles_controller を作成する必要があります。g controller を実行すると以下に示すファイルが作成されています。generator.rb でかなりのものを false にしたので必要最低限のものしか作成されていません。

$ bin/rails g controller articles index --skip-routes
      create  app/controllers/articles_controller.rb
      invoke  haml
      create    app/views/articles
      create    app/views/articles/index.html.haml
      invoke  rspec
      create    spec/requests/articles_spec.rb

ここで、spec/requests/articles_spec.rb が作成されるのですが、先日作った雛形のものではありません。

require 'rails_helper'

RSpec.describe "Articles", type: :request do
  describe "GET /index" do
    it "returns http success" do
      get "/articles/index"
      expect(response).to have_http_status(:success)
    end
  end

end

実は、先日用意したテンプレートは integration_test のものでした。ここで以下のように integration_test の generator を再度実行し、上書きをします。

> bin/rails g integration_test articles
      invoke  rspec
    conflict    spec/requests/articles_spec.rb
  Overwrite /Users/hkob/Library/CloudStorage/Dropbox/rails/hkob_blog/spec/requests/articles_spec.rb? (enter "h" for help) [Ynaqdhm] 
       force    spec/requests/articles_spec.rb

作成した request spec の index の部分だけを生かしました。以下の修正をしています。

  • 1行目の rubocop の # rubocop:disable all を消しました。
  • describe の後ろを文字列ではなく Controller のクラス名にしました。
  • まだログインしていないので所有などの概念はないため権限周りの部分は外しています。
  • Hello, Rails!表示されることを確認します。
require "rails_helper"

RSpec.describe ArticlesController, type: :request do
  # let!(:article) { articles :can_delete }
  # let!(:object) { article }
  # let!(:attrs) { object.attributes }
  # let(:not_mine) { articles :not_mine }

  # let(:return_path) { articles_path }
  # context "login by hkob" do
  #   user_login :hkob

  describe "GET #index" do
    subject { -> { get articles_path } }
    it_behaves_like "レスポンスコード確認", 200
    it_behaves_like "描画結果に文字列が含まれている?", %w[Hello Rails!]
  end

保存すると guard のテストが実行され、以下のようなエラーになります。当然、まだ shared_example を用意していないので当然ですね。先に用意しておくべきでした。以前紹介したものを使うたびに shared_example.rb に追加していきましょう。

21:17:54 - INFO - Running: spec/requests/articles_spec.rb

An error occurred while loading ./spec/requests/articles_spec.rb.
Failure/Error: it_behaves_like "レスポンスコード確認", 200

ArgumentError:
  Could not find shared examples "レスポンスコード確認"
# ./spec/requests/articles_spec.rb:15:in `block (2 levels) in <top (required)>'
# ./spec/requests/articles_spec.rb:13:in `block in <top (required)>'
# ./spec/requests/articles_spec.rb:3:in `<top (required)>'
No examples found.

Finished in 0.00003 seconds (files took 1.74 seconds to load)
0 examples, 0 failures, 1 error occurred outside of examples

shared examle の追加

まだファイルも用意していなかったので、spec/support ディレクトリを作成し、その下に shared_exmpale.rb を追加します。

$ mkdir -p spec/support
$ touch spec/support/shared_example.rb

使っている shared_example はこちらの過去の記事に書かれています。

shared_example を保存すると再度テストが実行され、二つのうちの一つは通ったことが確認できます。失敗しているのは「Hello Rails?」がページに含まれているのテストが失敗しています。

Finished in 0.17995 seconds (files took 1.56 seconds to load)
2 examples, 1 failure

Failed examples:

rspec ./spec/requests/articles_spec.rb:16 # ArticlesController GET #index behaves like 描画結果に文字列が含まれている? レスポンスの文字列が「["Hello", "Rails!"]」を含むこと

このテストを通過させるために、ガイドの通りに app/views/articles/index.html.haml を以下のように修正しましょう。

%h1 Hello, Rails!

view が書きかわったら以下のようにテストが全部通過しました。

21:30:14 - INFO - Running: spec/requests/articles_spec.rb

ArticlesController
  GET #index
    behaves like レスポンスコード確認
      レスポンスのステータスが 200 であること
    behaves like 描画結果に文字列が含まれている?
      レスポンスの文字列が「["Hello", "Rails!"]」を含むこと

Finished in 0.07406 seconds (files took 1.54 seconds to load)
2 examples, 0 failures

実際にブラウザで http://localhost:3000/articles を確認すると確かに Hello, Rails! が表示されていることが確認できました。

Hello Rails

おわりに

Rails ガイドではテストを記述していませんが、この記事では必ずテストを書き、テスト失敗を確認した上で実装を記述していきます。