マイクロポストを操作する
データモデリングとマイクロポスト表示テンプレートの両方が完成したので、次はWeb経由でそれらを作成するためのインターフェイスに取りかかりましょう。
インターフェース
IT関連では、二つのものが接続・接触する箇所や、両者の間で情報や信号などをやりとりするための手順や規約を定めたものを意味する
最後に、ユーザーがマイクロポストをWeb経由で破棄できるようにします。
マイクロポストリソースのルーティング
config/routes.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
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
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
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
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フィルターを残したままにするとマズイのでしょうか? 考えてみてください。
わからなかった。
調べてみると
コードが重複してしまうためらしい。