Persist notification's creator

Instead of delegating. With a polymorphic relationship, relying on a certain
attribute implies doing things like aliasing "mentioner" to "creator" or similar.
This commit is contained in:
Jorge Manrubia
2025-04-22 13:48:43 +02:00
parent 4f06473405
commit 8aa99e34b4
11 changed files with 53 additions and 19 deletions
+1 -1
View File
@@ -2,6 +2,6 @@ class Mention < ApplicationRecord
include Notifiable
belongs_to :container, polymorphic: true
belongs_to :creator, class_name: "User"
belongs_to :mentioner, class_name: "User"
belongs_to :mentionee, class_name: "User", inverse_of: :mentions
end
+1 -1
View File
@@ -1,5 +1,6 @@
class Notification < ApplicationRecord
belongs_to :user
belongs_to :creator, class_name: "User"
belongs_to :source, polymorphic: true
belongs_to :resource, polymorphic: true
@@ -7,7 +8,6 @@ class Notification < ApplicationRecord
scope :read, -> { where.not(read_at: nil) }
scope :ordered, -> { order(read_at: :desc, created_at: :desc) }
delegate :creator, to: :source
after_create_commit :broadcast_unread
def self.read_all
+1 -3
View File
@@ -1,8 +1,6 @@
class Notifier
attr_reader :source
delegate :creator, to: :source
class << self
def for(source)
case source
@@ -17,7 +15,7 @@ class Notifier
def notify
if should_notify?
recipients.map do |recipient|
Notification.create! user: recipient, source: source, resource: resource
Notification.create! user: recipient, source: source, resource: resource, creator: creator
end
end
end
+1 -1
View File
@@ -1,5 +1,5 @@
class Notifier::Events::Base < Notifier
delegate :card, to: :source
delegate :card, :creator, to: :source
private
def should_notify?
+4
View File
@@ -7,4 +7,8 @@ class Notifier::Mention < Notifier
def recipients
[ source.mentionee ]
end
def creator
source.mentioner
end
end
+1 -1
View File
@@ -6,7 +6,7 @@ module User::Mentionable
end
def mentioned_by(mentioner, at:)
mentions.create! container: at, creator: mentioner
mentions.create! container: at, mentioner: mentioner
end
def mentionable_handles
+1 -1
View File
@@ -3,7 +3,7 @@ class CreateMentions < ActiveRecord::Migration[8.1]
create_table :mentions do |t|
t.references :container, polymorphic: true, null: false, index: true
t.references :mentionee, foreign_key: { to_table: :users }, null: false
t.references :creator, foreign_key: { to_table: :users }, null: false
t.references :mentioner, foreign_key: { to_table: :users }, null: false
t.timestamps
end
Generated
+7 -4
View File
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.1].define(version: 2025_04_22_062930) do
ActiveRecord::Schema[8.1].define(version: 2025_04_22_112857) do
create_table "accesses", force: :cascade do |t|
t.integer "collection_id", null: false
t.datetime "created_at", null: false
@@ -216,12 +216,12 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_22_062930) do
t.integer "container_id", null: false
t.string "container_type", null: false
t.datetime "created_at", null: false
t.integer "creator_id", null: false
t.integer "mentionee_id", null: false
t.integer "mentioner_id", null: false
t.datetime "updated_at", null: false
t.index ["container_type", "container_id"], name: "index_mentions_on_container"
t.index ["creator_id"], name: "index_mentions_on_creator_id"
t.index ["mentionee_id"], name: "index_mentions_on_mentionee_id"
t.index ["mentioner_id"], name: "index_mentions_on_mentioner_id"
end
create_table "messages", force: :cascade do |t|
@@ -236,6 +236,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_22_062930) do
create_table "notifications", force: :cascade do |t|
t.datetime "created_at", null: false
t.integer "creator_id", null: false
t.datetime "read_at"
t.integer "resource_id", null: false
t.string "resource_type", null: false
@@ -243,6 +244,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_22_062930) do
t.string "source_type", null: false
t.datetime "updated_at", null: false
t.integer "user_id", null: false
t.index ["creator_id"], name: "index_notifications_on_creator_id"
t.index ["resource_type", "resource_id"], name: "index_notifications_on_resource"
t.index ["source_type", "source_id"], name: "index_notifications_on_source"
t.index ["user_id", "read_at", "created_at"], name: "index_notifications_on_user_id_and_read_at_and_created_at", order: { read_at: :desc, created_at: :desc }
@@ -339,10 +341,11 @@ ActiveRecord::Schema[8.1].define(version: 2025_04_22_062930) do
add_foreign_key "collections", "workflows"
add_foreign_key "events", "cards"
add_foreign_key "events", "event_summaries", column: "summary_id"
add_foreign_key "mentions", "users", column: "creator_id"
add_foreign_key "mentions", "users", column: "mentionee_id"
add_foreign_key "mentions", "users", column: "mentioner_id"
add_foreign_key "messages", "cards"
add_foreign_key "notifications", "users"
add_foreign_key "notifications", "users", column: "creator_id"
add_foreign_key "pins", "cards"
add_foreign_key "pins", "users"
add_foreign_key "sessions", "users"
+30 -4
View File
@@ -669,7 +669,16 @@ columns:
default_function:
collation:
comment:
- *23
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
auto_increment:
name: mentioner_id
cast_type: *1
sql_type_metadata: *2
'null': false
default:
default_function:
collation:
comment:
- *8
- *9
messages:
@@ -752,6 +761,7 @@ columns:
default_function:
collation:
comment:
- *23
pins:
- *5
- *21
@@ -1647,10 +1657,10 @@ indexes:
mentions:
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
table: mentions
name: index_mentions_on_creator_id
name: index_mentions_on_mentioner_id
unique: false
columns:
- creator_id
- mentioner_id
lengths: {}
orders: {}
opclasses: {}
@@ -1729,6 +1739,22 @@ indexes:
comment:
valid: true
notifications:
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
table: notifications
name: index_notifications_on_creator_id
unique: false
columns:
- creator_id
lengths: {}
orders: {}
opclasses: {}
where:
type:
using:
include:
nulls_not_distinct:
comment:
valid: true
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
table: notifications
name: index_notifications_on_source
@@ -2019,4 +2045,4 @@ indexes:
comment:
valid: true
workflows: []
version: 20250422062930
version: 20250422112857
@@ -15,9 +15,9 @@ class Cards::ReadingsControllerTest < ActionDispatch::IntegrationTest
test "read multiple notifications on card visit" do
assert_changes -> { notifications(:logo_published_kevin).reload.read? }, from: false, to: true do
assert_changes -> { notifications(:logo_assignment_kevin).reload.read? }, from: false, to: true do
post card_reading_path(cards(:logo)), as: :turbo_stream
end
assert_changes -> { notifications(:logo_assignment_kevin).reload.read? }, from: false, to: true do
post card_reading_path(cards(:logo)), as: :turbo_stream
end
end
assert_response :success
+3
View File
@@ -3,15 +3,18 @@ logo_published_kevin:
source: logo_published (Event)
resource: logo (Card)
created_at: <%= 1.week.ago %>
creator: david
logo_assignment_kevin:
user: kevin
source: logo_assignment_km (Event)
resource: logo (Card)
created_at: <%= 1.week.ago %>
creator: david
layout_commented_kevin:
user: kevin
source: layout_commented (Event)
resource: layout_overflowing_david (Comment)
created_at: <%= 1.week.ago %>
creator: david