###destroyアクション
destroyアクションへのリンクを追加
####ユーザー削除用リンクの実装(管理者にのみ表示される)
app/views/users/_user.html.erb
<li>
<%= gravatar_for user, size: 50 %>
<%= link_to user.name, user %>
<% if current_user.admin? && !current_user?(user
# 現在のユーザーが管理者のときに限り [delete] リンクが表示
| <%= link_to "delete", user, method: :delete
# DELETEリクエストを発行するリンクの生成は、
# method: :deleteによって行われている
data: { confirm: "You sure?" } %>
<% end %>
</li>
####実際に動作するdestroyアクションを追加する
app/controllers/users_controller.rb
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
.
.
.
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted"
redirect_to users_url
end
.
.
.
end
####beforeフィルターでdestroyアクションを管理者だけに限定する
app/controllers/users_controller.rb
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
# before_actionメソッドを使って何らかの処理が実行される直前に
# 特定のメソッドを実行する仕組み
# ログインをさせる
# :editと:updateアクションだけ
.
.
.
# 管理者かどうか確認
def admin_user
redirect_to(root_url) unless current_user.admin?
#管理者でなければホーム画面に移動する
end
end
###演習
1.
管理者ユーザーとしてログインし、試しにサンプルユーザを2〜3人削除してみましょう。ユーザーを削除すると、Railsサーバーのログにはどのような情報が表示されるでしょうか?
削除できたけどログに何がかてあるのかわからない。
###ユーザー削除のテスト
####fixture内の最初のユーザーを管理者にする
test/fixtures/users.yml
michael:
name: Michael Example
email: michael@example.com
password_digest: <%= User.digest('password') %>
admin: true
archer:
name: Sterling Archer
email: duchess@example.gov
password_digest: <%= User.digest('password') %>
lana:
name: Lana Kane
email: hands@example.gov
password_digest: <%= User.digest('password') %>
malory:
name: Malory Archer
email: boss@example.gov
password_digest: <%= User.digest('password') %>
<% 30.times do |n| %>
# さらに30人のユーザーを追加
user_<%= n %>:
name: <%= "User #{n}" %>
email: <%= "user-#{n}@example.com" %>
password_digest: <%= User.digest('password') %>
<% end %>
####管理者権限の制御をアクションレベルでテストする
test/controllers/users_controller_test.rb
require 'test_helper'
class UsersControllerTest < ActionDispatch::IntegrationTest
def setup
@user = users(:michael)
@other_user = users(:archer)
# テストユーザー
end
.
.
.
test "should redirect destroy when not logged in" do
# ログインしていないユーザーであれば、ログイン画面にリダイレクト
assert_no_difference 'User.count' do
delete user_path(@user)
end
assert_redirected_to login_url
end
test "should redirect destroy when logged in as a non-admin" do
# ログイン済みではあっても管理者でなければ、ホーム画面にリダイレクト
log_in_as(@other_user)
assert_no_difference 'User.count' do
# 数が変わらないか?
delete user_path(@user)
#削除のリクエスト
end
assert_redirected_to root_url
end
end
####削除リンクとユーザー削除に対する統合テスト
test/integration/users_index_test.rb
require 'test_helper'
class UsersIndexTest < ActionDispatch::IntegrationTest
def setup
@admin = users(:michael)
@non_admin = users(:archer)
end
test "index as admin including pagination and delete links" do
log_in_as(@admin)
# ログインして
get users_path
assert_template 'users/index'
assert_select 'div.pagination'
first_page_of_users = User.paginate(page: 1)
first_page_of_users.each do |user|
assert_select 'a[href=?]', user_path(user), text: user.name
# ちゃんと表示されているかどうか?
unless user == @admin
assert_select 'a[href=?]', user_path(user), text: 'delete'
# 削除リンクのテスト
end
end
assert_difference 'User.count', -1 do
# 削除の差分が1かどうか?
delete user_path(@non_admin)
end
end
test "index as non-admin" do
log_in_as(@non_admin)
get users_path
assert_select 'a', text: 'delete', count: 0
# user allにdeleteのリンクはついて無いかどうか?
end
end
buntu:~/environment/sample_app (updating-users) $ rails t
Running via Spring preloader in process 14304
Started with run options --seed 40769
43/43: [============================] 100% Time: 00:00:03, Time: 00:00:03
Finished in 3.93045s
43 tests, 168 assertions, 0 failures, 0 errors, 0 skips
###演習
1.
管理者ユーザーとしてログインし、試しにサンプルユーザを2〜3人削除してみましょう。ユーザーを削除すると、Railsサーバーのログにはどのような情報が表示されるでしょうか?
ubuntu:~/environment/sample_app (updating-users) $ rails t
Running via Spring preloader in process 15299
Started with run options --seed 24552
FAIL["test_should_redirect_destroy_when_logged_in_as_a_non-admin", #<Minitest::Reporters::Suite:0x000056497493d550 @name="UsersControllerTest">, 1.8115053430010448]
test_should_redirect_destroy_when_logged_in_as_a_non-admin#UsersControllerTest (1.81s)
"User.count" didn't change by 0.
Expected: 34
Actual: 33
test/controllers/users_controller_test.rb:76:in `block in <class:UsersControllerTest>'
43/43: [============================] 100% Time: 00:00:02, Time: 00:00:02
Finished in 2.55566s
43 tests, 167 assertions, 1 failures, 0 errors, 0 skips
多分削除されている。
admin_userが機能していないから
テストで引っかかっていると思う。