Skip to content

Commit e5954f1

Browse files
committed
Notify people when they have been added or removed as an author
1 parent 182fcd2 commit e5954f1

File tree

7 files changed

+1570
-1336
lines changed

7 files changed

+1570
-1336
lines changed

app/controllers/better_together/pages_controller.rb

Lines changed: 47 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -32,24 +32,26 @@ def create # rubocop:todo Metrics/MethodLength, Metrics/AbcSize
3232
@page = resource_class.new(page_params)
3333
authorize @page
3434

35-
respond_to do |format|
36-
if @page.save
37-
format.html do
38-
redirect_to edit_page_path(@page), notice: t('flash.generic.created', resource: t('resources.page'))
39-
end
40-
format.turbo_stream do
41-
flash.now[:notice] = t('flash.generic.created', resource: t('resources.page'))
42-
render turbo_stream: turbo_stream.redirect_to(edit_page_path(@page))
43-
end
44-
else
45-
format.turbo_stream do
46-
render turbo_stream: turbo_stream.update(
47-
'form_errors',
48-
partial: 'layouts/better_together/errors',
49-
locals: { object: @page }
50-
)
35+
BetterTogether::Authorship.with_creator(helpers.current_person) do
36+
respond_to do |format|
37+
if @page.save
38+
format.html do
39+
redirect_to edit_page_path(@page), notice: t('flash.generic.created', resource: t('resources.page'))
40+
end
41+
format.turbo_stream do
42+
flash.now[:notice] = t('flash.generic.created', resource: t('resources.page'))
43+
render turbo_stream: turbo_stream.redirect_to(edit_page_path(@page))
44+
end
45+
else
46+
format.turbo_stream do
47+
render turbo_stream: turbo_stream.update(
48+
'form_errors',
49+
partial: 'layouts/better_together/errors',
50+
locals: { object: @page }
51+
)
52+
end
53+
format.html { render :new, status: :unprocessable_entity }
5154
end
52-
format.html { render :new, status: :unprocessable_entity }
5355
end
5456
end
5557
end
@@ -61,32 +63,34 @@ def edit
6163
def update # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
6264
authorize @page
6365

64-
respond_to do |format| # rubocop:todo Metrics/BlockLength
65-
if @page.update(page_params)
66-
format.html do
67-
flash[:notice] = t('flash.generic.updated', resource: t('resources.page'))
68-
redirect_to edit_page_path(@page), notice: t('flash.generic.updated', resource: t('resources.page'))
69-
end
70-
format.turbo_stream do
71-
flash.now[:notice] = t('flash.generic.updated', resource: t('resources.page'))
72-
render turbo_stream: [
73-
turbo_stream.replace(helpers.dom_id(@page, 'form'), partial: 'form',
74-
locals: { page: @page }),
75-
turbo_stream.replace('flash_messages', partial: 'layouts/better_together/flash_messages',
76-
locals: { flash: })
77-
]
78-
end
79-
else
80-
format.html { render :edit }
81-
format.turbo_stream do
82-
render turbo_stream: [
83-
turbo_stream.replace(helpers.dom_id(@page, 'form'), partial: 'form', locals: { page: @page }),
84-
turbo_stream.update(
85-
'form_errors',
86-
partial: 'layouts/better_together/errors',
87-
locals: { object: @page }
88-
)
89-
]
66+
BetterTogether::Authorship.with_creator(helpers.current_person) do # rubocop:todo Metrics/BlockLength
67+
respond_to do |format| # rubocop:todo Metrics/BlockLength
68+
if @page.update(page_params)
69+
format.html do
70+
flash[:notice] = t('flash.generic.updated', resource: t('resources.page'))
71+
redirect_to edit_page_path(@page), notice: t('flash.generic.updated', resource: t('resources.page'))
72+
end
73+
format.turbo_stream do
74+
flash.now[:notice] = t('flash.generic.updated', resource: t('resources.page'))
75+
render turbo_stream: [
76+
turbo_stream.replace(helpers.dom_id(@page, 'form'), partial: 'form',
77+
locals: { page: @page }),
78+
turbo_stream.replace('flash_messages', partial: 'layouts/better_together/flash_messages',
79+
locals: { flash: })
80+
]
81+
end
82+
else
83+
format.html { render :edit }
84+
format.turbo_stream do
85+
render turbo_stream: [
86+
turbo_stream.replace(helpers.dom_id(@page, 'form'), partial: 'form', locals: { page: @page }),
87+
turbo_stream.update(
88+
'form_errors',
89+
partial: 'layouts/better_together/errors',
90+
locals: { object: @page }
91+
)
92+
]
93+
end
9094
end
9195
end
9296
end

app/models/better_together/authorship.rb

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@ module BetterTogether
44
# Connects an author (eg: person) to an authorable (eg: post)
55
class Authorship < ApplicationRecord
66
include Positioned
7+
include BetterTogether::Creatable
8+
9+
# Per-request creator context for assigning creator_id during author adds
10+
thread_mattr_accessor :creator_context_id
11+
12+
before_validation :assign_creator_from_context, on: :create
13+
14+
# Set creator context for any authorship creations within the block
15+
def self.with_creator(person)
16+
previous = creator_context_id
17+
self.creator_context_id = person&.id
18+
yield
19+
ensure
20+
self.creator_context_id = previous
21+
end
722

823
belongs_to :author,
924
class_name: 'BetterTogether::Person'
@@ -16,8 +31,21 @@ class Authorship < ApplicationRecord
1631

1732
private
1833

19-
def notify_added_to_page
34+
def assign_creator_from_context
35+
self.creator_id ||= self.class.creator_context_id
36+
end
37+
38+
# rubocop:todo Metrics/AbcSize
39+
# rubocop:todo Metrics/PerceivedComplexity
40+
# rubocop:todo Metrics/MethodLength
41+
# rubocop:todo Metrics/CyclomaticComplexity
42+
def notify_added_to_page # rubocop:todo Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
2043
return unless authorable.is_a?(BetterTogether::Page)
44+
# Skip notifying if the assigned author created this authorship
45+
return if creator_id.present? && creator_id == author_id
46+
47+
# Also skip if the current actor is the same person being added
48+
return if defined?(::Current) && ::Current.respond_to?(:person) && (::Current.person&.id == author_id)
2149

2250
actor = defined?(::Current) && ::Current.respond_to?(:person) ? ::Current.person : nil
2351
BetterTogether::PageAuthorshipNotifier
@@ -28,10 +56,21 @@ def notify_added_to_page
2856
actor_name: actor&.name)
2957
.deliver_later(author)
3058
end
59+
# rubocop:enable Metrics/CyclomaticComplexity
60+
# rubocop:enable Metrics/MethodLength
61+
# rubocop:enable Metrics/PerceivedComplexity
3162

32-
def notify_removed_from_page
63+
# rubocop:enable Metrics/AbcSize
64+
# rubocop:todo Metrics/MethodLength
65+
def notify_removed_from_page # rubocop:todo Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
3366
return unless authorable.is_a?(BetterTogether::Page)
3467

68+
# Skip notifying when the acting person equals the removed author.
69+
# Prefer creator_context_id (thread-local) when provided, otherwise fall back to Current.person when available.
70+
return if self.class.creator_context_id.present? && self.class.creator_context_id == author_id
71+
# Skip notifying if the person removing is the same as the removed author
72+
return if defined?(::Current) && ::Current.respond_to?(:person) && (::Current.person&.id == author_id)
73+
3574
actor = defined?(::Current) && ::Current.respond_to?(:person) ? ::Current.person : nil
3675
BetterTogether::PageAuthorshipNotifier
3776
.with(record: authorable,
@@ -41,5 +80,6 @@ def notify_removed_from_page
4180
actor_name: actor&.name)
4281
.deliver_later(author)
4382
end
83+
# rubocop:enable Metrics/MethodLength
4484
end
4585
end

app/models/better_together/page.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ module BetterTogether
44
# An informational document used to display custom content to the user
55
class Page < ApplicationRecord
66
include Authorable
7+
# When adding authors via `author_ids=` or association ops, controllers can
8+
# set BetterTogether::Authorship.creator_context_id = current_person.id
9+
# to stamp newly-created authorships with the acting person.
710
include Categorizable
811
include Identifier
912
include Protected

app/notifiers/better_together/page_authorship_notifier.rb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ def url
7272
page.url
7373
end
7474

75-
# rubocop:todo Metrics/PerceivedComplexity
7675
# rubocop:todo Metrics/MethodLength
7776
def title # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
7877
name = actor_name || actor&.name
@@ -88,9 +87,8 @@ def title # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
8887
I18n.t('better_together.page_authorship_notifier.added', page_title: page.title)
8988
end
9089
end
91-
# rubocop:enable Metrics/MethodLength
92-
# rubocop:enable Metrics/PerceivedComplexity
9390

91+
# rubocop:enable Metrics/MethodLength
9492
def body
9593
# Keep body concise; UI partial will display details
9694
title
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# frozen_string_literal: true
2+
3+
class AddCreatorToBetterTogetherAuthorships < ActiveRecord::Migration[7.1] # rubocop:todo Style/Documentation
4+
def change
5+
add_column :better_together_authorships, :creator_id, :uuid
6+
add_index :better_together_authorships, :creator_id, name: 'by_better_together_authorships_creator'
7+
end
8+
end

0 commit comments

Comments
 (0)