ぞえの技術めも

Ruby on Rails勉強中

【152日目】【1日20分のRailsチュートリアル】【第11章】マイクロポストのアクセス制御を実装する

Ruby on Railsチュートリアル(第3版)

今日は「11.3 マイクロポストを操作する」から。

11.3 マイクロポストを操作する

データモデリングとマイクロポスト表示テンプレートの両方が完成したので、次はWeb経由でそれらを作成するためのインターフェイスに取りかかりましょう。

Twitterでいう新規ツイートするフォームかな。

Micropostsリソースへのインターフェイスは、主にProfileページとHomeページのコントローラを経由して実行されるので、Micropostsコントローラにはnewやeditのようなアクションは不要ということになります。

newも要らないのか。Micropostsを投稿する専用ページは設けないイメージかな…??

ルーティングファイルに下記を追加。

config/routes.rb

  resources :microposts,          only: [:create, :destroy]

11.3.1 マイクロポストのアクセス制御

関連付けられたユーザーを通してマイクロポストにアクセスするので、createアクションやdestroyアクションを利用するユーザーは、ログイン済みでなければなりません。

ふむふむ。確かにそうですね。
誰でも利用できる状態はまずいですね。

正しいリクエストを各アクションに向けて発行し、マイクロポストの数が変化していないかどうか、また、リダイレクトされるかどうかを確かめればよいのです (リスト11.30)。

createとdestroyアクションに対してテストを追加。

test/controllers/microposts_controller_test.rb

require 'test_helper'

class MicropostsControllerTest < ActionController::TestCase

  def setup
    @micropost = microposts(:orange)
  end

  test "should redirect create when not logged in" do
    assert_no_difference 'Micropost.count' do
      post :create, micropost: { content: "Lorem ipsum" }
    end
    assert_redirected_to login_url
  end

  test "should redirect destroy when not logged in" do
    assert_no_difference 'Micropost.count' do
      delete :destroy, id: @micropost
    end
    assert_redirected_to login_url
  end
end

実装してないのでテストは通りません。

$ bundle exec rake test
57 tests, 290 assertions, 0 failures, 2 errors, 0 skips

beforeフィルターのlogged_in_userメソッドを使って、ログインを要求したことについて思い出してください (リスト9.12)。
(中略)
そこで、各コントローラが継承するApplicationコントローラに (4.4.4)、このメソッドを移してしまいましょう。結果はリスト11.31のようになります。

各コントローラで使用するAPIはApplicationコントローラに定義すればいいのか…。

app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  include SessionsHelper

  private

    # ユーザーのログインを確認する
    def logged_in_user
      unless logged_in?
        store_location
        flash[:danger] = "Please log in."
        redirect_to login_url
      end
    end
end

コードが重複しないよう、このときUsersコントローラからもlogged_in_userを削除しておきましょう。

コメントアウトしておきました。

app/controllers/users_controller.rb

    # # ログイン済みユーザーかどうか確認
    # def logged_in_user
    #   unless logged_in?
    #     store_location
    #     flash[:danger] = "Please log in."
    #     redirect_to login_url
    #   end
    # end

これにより、createアクションやdestroyアクションに対するアクセス制限が、beforeフィルターで簡単に実装できるようになります (リスト11.32)。

Userコントローラと一緒の実装でOKなのかー。beforeフィルターとcreate/destroyアクションを追加。

app/controllers/microposts_controller.rb

class MicropostsController < ApplicationController
  before_action :logged_in_user, only: [:create, :destroy]

  def create
  end

  def destroy
  end
end

テスト通りました!

$ bundle exec rake test
57 tests, 294 assertions, 0 failures, 0 errors, 0 skips

今日の学習時間は【30分】

次は「11.3.2 マイクロポストを作成する」から。