Rails Tutorial 拡張機能のメッセージ機能を作ってみた(その5):削除機能
Rails Tutorialの第14章にある、メッセージ機能を作る件の続きです。
前回までで受信したDMが表示される機能ができました。
今回はDMを削除する機能を作ります。
DMを削除する機能の設計
DMを削除する機能を作ります。13.3.4を読みます。
micropostは自分が投稿したもののみ削除できました。DMでは、自分が受信したDMのみ削除できるようにします。削除はモデルを作った際に決めたとおり、deletedフラグをTRUEにします。
destroyアクション作成
destroyアクションを作ります。
「リスト 13.52: Micropostsコントローラのdestroyアクション 」を読みます。
削除対象のDMは、現在のユーザーが受信者になっているかをチェックします。
consoleで試してみます。
>> user1 = User.third
=> #<User id: 3, name: "Vivianne Sporer",
>> user1.received_dms
=> #<ActiveRecord::Associations::CollectionProxy [#<Dm id: 305, content: "content5", sender_id: 1, receiver_id: 3, deleted: false, created_at: "2020-11-23 23:18:33", updated_at: "2020-11-23 23:18:33">, #<Dm id: 304, content: "content4", sender_id: 1, receiver_id: 3, deleted: false, created_at: "2020-11-23 00:45:49", updated_at: "2020-11-23 00:45:49">,
>> dm1 = user1.received_dms.find_by(id: 305)
=> #<Dm id: 305, content: "content5", sender_id: 1, receiver_id: 3, deleted: false, created_at: "2020-11-23 23:18:33", updated_at: "2020-11-23 23:18:33">
>> dm1.nil?
=> false
削除はdeletedフラグをTRUEにする更新なので、参考にユーザーの更新を読みます。
「リスト 11.31: アカウントを有効化するeditアクション 」を参考にします。
user.update_attribute(:activated, true)
user.update_attribute(:activated_at, Time.zone.now)
試しに削除してみます。
コンソールで調べると、deletedフラグが正しく更新されています。
>> Dm.find(305)
=> #<Dm id: 305, content: "content5", sender_id: 1, receiver_id: 3, deleted: true, created_at: "2020-11-23 23:18:33", updated_at: "2020-11-29 02:02:01">
一覧画面では削除したのに表示されたままです。
chatを変更する必要があるからと分かりました。
コンソールでSQL文を確かめます。
>> Dm.where("sender_id = :user_id OR (receiver_id = :user_id AND deleted = :flag) ", user_id: 3, flag: false)
chatを変更します。
def chat
#Dm.where("sender_id = ?", id)
Dm.where("sender_id = :user_id OR (receiver_id = :user_id AND deleted = :flag) ", user_id: id, flag: false)
end
chatを変更したことで、直す必要があるところがあるかもしれないので確認していきます。
コントローラーdms_controller.rbを読みます。indexメソッドでchatを使っていますが直す必要はなさそうです。
テストを実行してみます。REDになりました。
ubuntu:~/environment/sample_app (create-dm) $ rails test
test_DM_interface#DmsTest (2.72s)
<Michael Example> expected but was
<from:Michael Example>..
Expected 0 to be >= 1.
test/integration/dms_test.rb:54:in `block in <class:DmsTest>'
前に行った「From」を加える変更をしたときに、テストも直す必要があったようです。どうやら変更後にテストをしていなかったようです。テストを修正しGREENになりました。
assert_select "span.user", "from:#{@user.name}"
削除のテストを書きます。「13.3.5 フィード画面のマイクロポストをテストする」を読みます。
テストする項目の一つ目は、receiverが自分以外のユーザーのマイクロポストは削除をしようとすると、適切にリダイレクトされることです。画面にはdeleteの選択肢が出ないので、このテストの対象は、人が画面から入力するケースではなく、クローラーなどのツールからPostするケースです。
「リスト 13.54: 間違ったユーザーによるマイクロポスト削除に対してテストする 」を読んで気が付いたのですが、
ログインしていないとDMの送信も削除もできないテストも必要そうなので、合わせて作ります。
「リスト 13.31: Micropostsコントローラの認可テスト」を参考にします。
def setup
@dm = dms(:morning)
end
..
test "should redirect create when not logged in" do
assert_no_difference 'Dm.count' do
post dms_path, params: { dm1: { content: "hogehoge",
receiver_name: "hoge_receiver" } }
end
assert_redirected_to login_url
end
test "should redirect destroy when not loggged in" do
assert_no_difference 'Dm.count' do
delete dm_path(@dm)
end
assert_redirected_to login_url
end
test "should redirect destroy from wrong user" do
log_in_as(users(:michael))
assert_no_difference 'Dm.count' do
delete dm_path(@dm)
end
assert_redirected_to dms_path
end
テストがGREENになりました。
削除のテスト作成
統合テストに削除を追加します。テスト項目は、
・DMの削除
・送信者のDMには [delete] リンクが表示されないことを確認
です。
test "DM interface" do
# 受信者が削除
assert_select 'a', text: 'delete'
first_dm = @receiver.received_dms.first
assert_difference ' Dm.count', -1 do
delete dm_path(first_dm)
end
実行するとREDになりました。deleteしても数が減っていません。
test_DM_interface#DmsTest (1.37s)
" Dm.count" didn't change by -1.
Expected: 34
Actual: 35
Dmの数は変わっていなくて、削除フラグを更新していたことを思い出しました。
# 受信者が削除
assert_select 'a', text: 'delete'
first_dm = @receiver.received_dms.first
assert_difference '@receiver.chat.count', -1 do
delete dm_path(first_dm)
end
GREENになりました。
送信者のDMには [delete] リンクが表示されないことを確認するテストを考えます。
送信者=受信者のケースを考えると、このテストは逆にして、
受信者が自分でないDMには[delete]リンクが表示されないことを確認
にしたほうがよいと考えました。
ユーザーの削除リンクのテストを読みます。
「[リスト 10.62: 削除リンクとユーザー削除に対する統合テスト 」にありました。
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
参考にしてテストを作り、GREENになりました。
# 受信者ば自分でないDMは削除リンクが表示されない
delete logout_path
log_in_as(@user)
get dms_path
first_page_of_chat_items = @user.chat.paginate(page: 1)
first_page_of_chat_items.each do |chat|
if chat.receiver_id == @user.id
assert_select 'a[href=?]', dm_path(chat), text: 'delete'
else
assert_select 'a[href=?]', dm_path(chat), text: 'delete', count: 0
end
end
すべてのテストがGREENになり、完成です。
所要時間
11/29から12/5までの5.0時間です。
メッセージ機能全体では、
10/31から12/5までの33.0時間です。
Author And Source
この問題について(Rails Tutorial 拡張機能のメッセージ機能を作ってみた(その5):削除機能), 我々は、より多くの情報をここで見つけました https://qiita.com/sadao2005/items/50a4c4eaf63f1c8d5a0f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .