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:
@@ -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,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,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,5 +1,5 @@
|
||||
class Notifier::Events::Base < Notifier
|
||||
delegate :card, to: :source
|
||||
delegate :card, :creator, to: :source
|
||||
|
||||
private
|
||||
def should_notify?
|
||||
|
||||
@@ -7,4 +7,8 @@ class Notifier::Mention < Notifier
|
||||
def recipients
|
||||
[ source.mentionee ]
|
||||
end
|
||||
|
||||
def creator
|
||||
source.mentioner
|
||||
end
|
||||
end
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Vendored
+3
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user