Micropost access control

開發 Microposts resource 的第一步,要在 Microposts controller 實現瀏覽限制開始:若想瀏覽 createdestroy action,使用者必須先登入。

針對這個要求的測試和 User controller 相應的測試類似,我們要使用正確的請求類型瀏覽這兩個 action,然後檢查 micropost 的數量有沒有變化,而且會重新導向到登入頁面:

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

在編寫讓這個測試能通過的 APP 程式碼之前,我們需要進行一些重構。

Section 9.2.1 我們定義了一個 before filter 調用了 logged_in_user 方法,要求瀏覽相關的 action 之前要先登入。那時,我們只需要在 User controller 裡使用這個 before filter,現在則是連 Microposts controller 也要使用。所以我們把這個 before filter 移到 Application controller 裡(所有 controllers 的基本類別):

app/controllers/application_controller.rb

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

  private

    # Confirms a logged-in user.
    def logged_in_user
      unless logged_in?
        store_location
        flash[:danger] = "Please log in."
        redirect_to login_url
      end
    end
end

為避免重複程式碼,也必須把 User controller 裡的 logged_in_user 方法刪除。

現在 Microposts controller 也可以使用 logged_in_user 方法了,我們在 Microposts controller 裡增加 createdestroy action,並使用 before filter 限制瀏覽:

app/controllers/microposts_controller.rb

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

  def create
  end

  def destroy
  end
end

現在執行測試應該會通過(Green):

$ bundle exec rake test