Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
70f4cb7
ペア変更時と日程変更時に通知を送る機能を実装
s-tone-gs Mar 18, 2026
c97c2bc
ペアワークのカレンダーに確定日が表示されるようにした
s-tone-gs Mar 18, 2026
22af76a
ペア取り消し機能を実装
s-tone-gs Mar 18, 2026
a16fa66
ペア取り消し時の通知を実装
s-tone-gs Mar 18, 2026
a0a988c
ペア変更時の通知に対するテストコードを作成
s-tone-gs Mar 19, 2026
5554d5e
ペアワークの日程変更の通知に対するテストコードを作成
s-tone-gs Mar 19, 2026
b7d636f
ペア取り消し機能のテストを作成
s-tone-gs Mar 19, 2026
484574e
ペア取り消し時の通知に対するテストを作成
s-tone-gs Mar 19, 2026
b2354ac
ペアワークの確定日がカレンダーに表示されることのテストを作成
s-tone-gs Mar 19, 2026
433635b
退会操作時に退会者がバディのペアワークがアンマッチされることのテストを作成
s-tone-gs Mar 23, 2026
a6ef8c1
pair_workのunmatchメソッドのテストを作成
s-tone-gs Mar 23, 2026
3127ce9
reservations_controllerにupdateアクションを追加
s-tone-gs Mar 24, 2026
f0f8085
rubocop:disable Metrics/MethodLengthを追加
s-tone-gs Mar 24, 2026
4ca0dde
ペア変更の通知を変更前のペアにも送るように変更
s-tone-gs Mar 26, 2026
37df376
ペアワークの追加機能のデザイン、文章を整えた
machida Mar 25, 2026
d208348
三項演算子がネストしいて可読性が低いため変数として切り出した
s-tone-gs Mar 26, 2026
ae6cc27
確定日の表示の変更に合わせてシステムテストを修正
s-tone-gs Mar 26, 2026
b056da2
ペアワークが修了した際の表示に対するシステムテストを追加
s-tone-gs Mar 26, 2026
e5e5c71
終了したペアワークの動作確認用のデータを追加
s-tone-gs Mar 26, 2026
6b09132
reserved_atもnilになっていることを検証してより堅牢にした
s-tone-gs Mar 26, 2026
295725c
ペアが削除された際に宛先がnilになる可能性があるのでフィルタ↓
s-tone-gs Mar 26, 2026
f1bf11e
ペアワークの希望日更新をaccepts_nested_attributes_forを使用したものに修正し、システムテストを追加
s-tone-gs Mar 26, 2026
538bfbc
通知メソッドの命名を修正
s-tone-gs Apr 15, 2026
e4bb597
使用されていないインスタンス変数を削除
s-tone-gs Apr 15, 2026
8cde432
同ファイル内の他の記述に倣って改行を追加
s-tone-gs Apr 15, 2026
30ae839
コントローラーの処理をモデルメソッドに移行
s-tone-gs Apr 20, 2026
884ce20
viewの検索ロジックをモデルに移動
s-tone-gs Apr 20, 2026
3149bb4
アサーションを修正
s-tone-gs Apr 20, 2026
96a6e48
テスト名を修正
s-tone-gs Apr 20, 2026
ca5e640
タイポを修正
s-tone-gs Apr 20, 2026
e3da2a0
不要なrubocop:disabledを削除
s-tone-gs Apr 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,16 @@
.pair-work-schedule-dates__cancel-action {
min-width: 20rem;
}

.pair-work-schedule-dates__text-danger {
color: var(--danger);
}

.pair-work-ended__table {
display: none;
margin-top: 1rem;
}

#show-ended-schedule:checked ~ .pair-work-ended__table {
display: block;
}
8 changes: 8 additions & 0 deletions app/assets/stylesheets/shared/blocks/form/_form-table.css
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@
-webkit-font-smoothing: antialiased;
color: var(--main);
}
.form-table .form-table__check.is-disabled {
background-color: var(--background-tint);
cursor: not-allowed;
}
.form-table .form-table__check.is-disabled label {
cursor: not-allowed;
opacity: 0.4;
}
.form-table.is-sticky thead th {
position: sticky;
top: 0;
Expand Down
27 changes: 26 additions & 1 deletion app/controllers/pair_works/reservations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,32 @@ def create
end
end

def destroy; end
def update
@pair_work = PairWork.find(params[:pair_work_id])
if @pair_work.reserve(pair_work_reservation_params)
ActiveSupport::Notifications.instrument('pair_work.reschedule', pair_work: @pair_work) if @pair_work.saved_change_to_reserved_at?
if @pair_work.saved_change_to_buddy_id?
ActiveSupport::Notifications.instrument('pair_work.rematch', pair_work: @pair_work, past_buddy: @pair_work.past_buddy)
end
redirect_to Redirection.determin_url(self, @pair_work), notice: @pair_work.generate_notice_message(:update_reserve)
else
@comments = @pair_work.comments.order(:created_at)
render 'pair_works/show'
end
end

def destroy
@pair_work = PairWork.find(params[:pair_work_id])
return if current_user != @pair_work.buddy

if @pair_work.unmatch
ActiveSupport::Notifications.instrument('pair_work.cancel', pair_work: @pair_work, sender: current_user)
redirect_to Redirection.determin_url(self, @pair_work), notice: @pair_work.generate_notice_message(:cancel)
else
@comments = @pair_work.comments.order(:created_at)
render 'pair_works/show'
end
end
Comment thread
coderabbitai[bot] marked this conversation as resolved.

private

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/pair_works_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def index
@pair_works = PairWork.by_target(params[:target])
.with_avatar
.includes(:practice, :comments, :user)
.order(:published_at)
.order(published_at: :desc)
.page(params[:page])
.per(PAGER_NUMBER)
@pair_works_property = PairWork.generate_pair_works_property(params[:target])
Expand Down
57 changes: 57 additions & 0 deletions app/mailers/activity_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -508,4 +508,61 @@ def matching_pair_work(args = {})
message.perform_deliveries = @user.mail_notification? && !@user.retired?
message
end

def rematching_pair_work(args = {})
@receiver ||= args[:receiver]
@pair_work ||= args[:pair_work]

matched_user = @pair_work.buddy
@user = @receiver
@title = "ペアワーク【 #{@pair_work.title} 】のペアが#{matched_user.login_name}さんに変更になりました。"

@link_url = notification_redirector_url(
link: "/pair_works/#{@pair_work.id}",
kind: Notification.kinds[:rematching_pair_work]
)

subject = "[FBC] ペアワーク【 #{@pair_work.title} 】のペアが#{matched_user.login_name}さんに変更になりました。"
message = mail(to: @user.email, subject:)

message.perform_deliveries = @user.mail_notification? && !@user.retired?
message
end

def reschedule_pair_work(args = {})
@receiver ||= args[:receiver]
@pair_work ||= args[:pair_work]

@user = @receiver
@title = "ペアワーク【 #{@pair_work.title} 】の日程が#{I18n.l @pair_work.reserved_at}に変更になりました。"

@link_url = notification_redirector_url(
link: "/pair_works/#{@pair_work.id}",
kind: Notification.kinds[:reschedule_pair_work]
)

subject = "[FBC] ペアワーク【 #{@pair_work.title} 】の日程が#{I18n.l @pair_work.reserved_at}に変更になりました。"
message = mail(to: @user.email, subject:)

message.perform_deliveries = @user.mail_notification? && !@user.retired?
message
end

def cancel_pair_work(args = {})
@receiver ||= args[:receiver]
@pair_work ||= args[:pair_work]

@user = @receiver
@title = "ペアワーク【 #{@pair_work.title} 】のペア確定が取り消されました。"

@link_url = notification_redirector_url(
link: "/pair_works/#{@pair_work.id}",
kind: Notification.kinds[:cancel_pair_work]
)

subject = "[FBC] #{@pair_work.user.login_name}さんのペアワーク【 #{@pair_work.title} 】のペア確定が取り消されました。"
message = mail(to: @receiver.email, subject:)
message.perform_deliveries = @receiver.mail_notification? && !@receiver.retired?
message
end
end
5 changes: 4 additions & 1 deletion app/models/notification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ class Notification < ApplicationRecord
came_inquiry: 26,
training_completed: 27,
came_pair_work: 28,
matching_pair_work: 29
matching_pair_work: 29,
rematching_pair_work: 30,
reschedule_pair_work: 31,
cancel_pair_work: 32
}

scope :unreads, -> { where(read: false) }
Expand Down
22 changes: 21 additions & 1 deletion app/models/pair_work.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

# rubocop:disable Metrics/ClassLength
class PairWork < ApplicationRecord
include Searchable
include Commentable
Expand Down Expand Up @@ -86,7 +87,9 @@ def generate_notice_message(action_name)
create: 'ペアワークを作成しました。',
update: 'ペアワークを更新しました。',
destroy: 'ペアワークを削除しました。',
reserve: 'ペアが確定しました。'
reserve: 'ペアが確定しました。',
update_reserve: '予約内容を変更しました。',
cancel: 'ペア確定を取り消しました'
}[action_name]
end

Expand All @@ -99,6 +102,22 @@ def reserve(params)
save(context: :reserve)
end

def unmatch
return if reserved_at <= Time.current

update(buddy_id: nil, reserved_at: nil)
end

def past_buddy
return nil if buddy_id_before_last_save.blank?

User.find_by(id: buddy_id_before_last_save)
end

def find_scheduled_at(target_time)
schedules.find { |s| s.proposed_at == target_time }
end

private

def will_be_published?
Expand All @@ -113,3 +132,4 @@ def reserved_at_in_schedules
errors.add(:reserved_at, 'は提案されたスケジュールに含まれていません') unless schedules.map(&:proposed_at).include?(reserved_at)
end
end
# rubocop:enable Metrics/ClassLength
16 changes: 16 additions & 0 deletions app/models/pair_work_cancel_notifier.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

class PairWorkCancelNotifier
def call(_name, _started, _finished, _unique_id, payload)
notify_watchers(payload[:pair_work], payload[:sender])
end

private

def notify_watchers(pair_work, sender)
receivers = User.where(id: pair_work.watches.select(:user_id))
receivers.each do |receiver|
ActivityDelivery.with(pair_work:, receiver:, sender:).notify(:cancel_pair_work)
end
end
end
19 changes: 19 additions & 0 deletions app/models/pair_work_rematching_notifier.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

class PairWorkRematchingNotifier
def call(_name, _started, _finished, _unique_id, payload)
pair_work = payload[:pair_work]
past_buddy = payload[:past_buddy]
return if pair_work.wip?

notify_pair_work_creator_and_past_buddy(pair_work, past_buddy)
end

private

def notify_pair_work_creator_and_past_buddy(pair_work, past_buddy)
[pair_work.user, past_buddy].compact.each do |receiver|
ActivityDelivery.with(pair_work:, receiver:).notify(:rematching_pair_work)
end
end
end
16 changes: 16 additions & 0 deletions app/models/pair_work_reschedule_notifier.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

class PairWorkRescheduleNotifier
def call(_name, _started, _finished, _unique_id, payload)
pair_work = payload[:pair_work]
return if pair_work.wip?

notify_pair_work_creator(pair_work)
end

private

def notify_pair_work_creator(pair_work)
ActivityDelivery.with(pair_work:, receiver: pair_work.user).notify(:reschedule_pair_work)
end
end
7 changes: 7 additions & 0 deletions app/models/retirement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def execute
clean_up_regular_events
clear_github_info
destroy_cards
unmatch_pair_works
publish
notify
true
Expand Down Expand Up @@ -77,6 +78,12 @@ def clean_up_regular_events
@user.clean_up_regular_events
end

def unmatch_pair_works
PairWork.where(buddy: @user).find_each do |pair_work|
ActiveSupport::Notifications.instrument('pair_work.cancel', pair_work: pair_work, sender: @user) if pair_work.unmatch
end
end

def publish
ActiveSupport::Notifications.instrument('retirement.create', user: @user)
end
Expand Down
48 changes: 48 additions & 0 deletions app/notifiers/activity_notifier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,54 @@ def matching_pair_work(params = {})
)
end

def rematching_pair_work(params = {})
params.merge!(@params)
pair_work = params[:pair_work]
sender = pair_work.buddy
receiver = params[:receiver]

notification(
body: "ペアワーク「#{pair_work.title}」のペアが#{sender.login_name}に変更されました。",
kind: :rematching_pair_work,
receiver:,
sender:,
link: Rails.application.routes.url_helpers.polymorphic_path(pair_work),
read: false
)
end

def reschedule_pair_work(params = {})
params.merge!(@params)
pair_work = params[:pair_work]
sender = pair_work.buddy
receiver = params[:receiver]

notification(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

他の記述と揃えてnotification() の上に空行を入れても良いかも知れません。

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同ファイル内の他の記述に倣って改行を追加にて修正しました。改行を入れない理由もなかったので他に倣いました🫡

body: "ペアワーク「#{pair_work.title}」の日程が#{I18n.l pair_work.reserved_at}に変更されました。",
kind: :reschedule_pair_work,
receiver:,
sender:,
link: Rails.application.routes.url_helpers.polymorphic_path(pair_work),
read: false
)
end

def cancel_pair_work(params = {})
params.merge!(@params)
pair_work = params[:pair_work]
sender = params[:sender]
receiver = params[:receiver]

notification(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

他の記述と揃えてnotification() の上に空行を入れても良いかも知れません。

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#9812 (comment) と同様に修正しました!

body: "ペアワーク「#{pair_work.title}」のペア確定が取り消されました。",
kind: :cancel_pair_work,
receiver:,
sender:,
link: Rails.application.routes.url_helpers.polymorphic_path(pair_work),
read: false
)
end

def moved_up_event_waiting_user(params = {})
params.merge!(@params)
event = params[:event]
Expand Down
9 changes: 9 additions & 0 deletions app/views/activity_mailer/cancel_pair_work.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
= render '/notification_mailer/notification_mailer_template',
title: @title,
link_url: @link_url,
link_text: 'ペアワークのページへ' do
p #{@pair_work.user.login_name}さんのペアワーク【 #{@pair_work.title} 】のペア確定が取り消されました。
div(style='border-top: solid 1px #ccc; height: 0;')
h1(style='margin-top: 1em; border-left: solid 6px #4638a0; padding: 0 0 0 1rem; font-size: 1.5em; border-bottom: none; color: #444444;')
= @pair_work.title
= md2html(@pair_work.description)
9 changes: 9 additions & 0 deletions app/views/activity_mailer/rematching_pair_work.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
= render '/notification_mailer/notification_mailer_template',
title: @title,
link_url: @link_url,
link_text: 'ペアワークのページへ' do
p ペアワーク【 #{@pair_work.title} 】のペアが#{@pair_work.buddy.login_name}に変更になりました。
div(style='border-top: solid 1px #ccc; height: 0;')
h1(style='margin-top: 1em; border-left: solid 6px #4638a0; padding: 0 0 0 1rem; font-size: 1.5em; border-bottom: none; color: #444444;')
= @pair_work.title
= md2html(@pair_work.description)
9 changes: 9 additions & 0 deletions app/views/activity_mailer/reschedule_pair_work.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
= render '/notification_mailer/notification_mailer_template',
title: @title,
link_url: @link_url,
link_text: 'ペアワークのページへ' do
p ペアワーク【 #{@pair_work.title} 】の日程が#{I18n.l @pair_work.reserved_at}に変更になりました。
div(style='border-top: solid 1px #ccc; height: 0;')
h1(style='margin-top: 1em; border-left: solid 6px #4638a0; padding: 0 0 0 1rem; font-size: 1.5em; border-bottom: none; color: #444444;')
= @pair_work.title
= md2html(@pair_work.description)
Loading
Loading