railsチュートリアル第１３章 マイクロポストを操作する

###マイクロポストを操作する
データモデリングとマイクロポスト表示テンプレートの両方が完成したので、次はWeb経由でそれらを作成するためのインターフェイスに取りかかりましょう。
#####インターフェース
IT関連では、二つのものが接続・接触する箇所や、両者の間で情報や信号などをやりとりするための手順や規約を定めたものを意味する

最後に、ユーザーがマイクロポストをWeb経由で破棄できるようにします。

####マイクロポストリソースのルーティング
config/routes.rb

```rb
Rails.application.routes.draw do
.
.
.
  # /users/1の有効にするため
  resources :account_activations, only: [:edit]
  # editアクションへの名前付きルートが必要になるため
  # ルーティングのアカウント有効化
  resources :password_resets,     only: [:new, :create, :edit, :update]
  # 新しいパスワードを再設定するためのフォームと、Userモデル内のパスワードを変更するため
  resources :microposts,          only: [:create, :destroy]
  # マイクロポストにはcreate,destroyあれば十分
  # RESTfulなルーティングのサブセットになります。
  # サブセットとは、一部分、部分集合、下位集合などの意味を持つ英単語  
end 
```
HTTPリクエスト　　　　URL　　　　アクション  　　名前付きルート
POST 　　　　　　　/microposts	　　　create	　　　microposts_path
DELETE	　　　　　　/microposts/1	　　destroy	　　　micropost_path(micropost)

###マイクロポストのアクセス制御
####Micropostsコントローラの認可テスト
test/controllers/microposts_controller_test.rb

```rb
require 'test_helper'

class MicropostsControllerTest < ActionDispatch::IntegrationTest

  def setup
    @micropost = microposts(:orange)
    # サンプルのマイクロポスト
  end

  test "should redirect create when not logged in" do
    assert_no_difference 'Micropost.count' do
    # マイクロポストの数を数えて違いがないかを確認
      post microposts_path, params: { micropost: { content: "Lorem ipsum" }}
      # マイクロポストを投稿する
      # 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 micropost_path(@micropost)
      # マイクロポストを削除
    end
    assert_redirected_to login_url
    # ログインページに転送
  end
end
```

####logged_in_userメソッドをApplicationコントローラに移す
app/controllers/application_controller.rb

```rb
class ApplicationController < ActionController::Base
  include SessionsHelper

  private
  # クラスの外からは呼び出せない。
  #   同じインスタンス内でのみ、関数形式で呼び出せる。

    # ユーザーのログインを確認する
    def logged_in_user
      unless logged_in?
      # ログインされていないかどうか？
        store_location
        # session[:forwarding_url] = request.url if request.get?
        # アクセスしようとしたURLを覚えておく
        # request リクエストを送ってきたユーザのヘッダー情報や
        #   環境変数を取得
        flash[:danger] = "Please log in."
        # ログインされていなかったらメッセージを送る
        redirect_to login_url
        # ログインページに送る
      end
    end
end
```

####Usersコントローラ内のlogged_in_userフィルターを削除する
app/controllers/users_controller.rb

```rb
class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
  .
  .
  .
  private
.
.
.    
    # 正しいユーザーかどうか確認
    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_url) unless current_user?(@user)
      # データベースと照らし合わせて無かったらホーム画面にいく。
    end
    
    # 管理者かどうか確認
    def admin_user
      redirect_to(root_url) unless current_user.admin?
      #管理者でなければホーム画面に移動する
    end
end
```

####Micropostsコントローラの各アクションに認可を追加する
app/controllers/microposts_controller.rb

```rb
class MicropostsController < ApplicationController
  before_action :logged_in_user, only: [:create, :destroy]
  # create,destroyを行う前にログインを求めらえれる。

  def create
  end

  def destroy
  end
end
```

#####テスト
```
ubuntu:~/environment/sample_app (user-microposts) $ rails t
Running via Spring preloader in process 15532
Started with run options --seed 8815

  56/56: [===========================] 100% Time: 00:00:04, Time: 00:00:04

Finished in 4.11320s
56 tests, 293 assertions, 0 failures, 0 errors, 0 skips
```

###演習
1.
なぜUsersコントローラ内にあるlogged_in_userフィルターを残したままにするとマズイのでしょうか? 考えてみてください。
わからなかった。
調べてみると
コードが重複してしまうためらしい。