diff --git a/app/models/comment.rb b/app/models/comment.rb index 30706e8b5..41e068514 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -4,7 +4,7 @@ class Comment < ApplicationRecord belongs_to :account, default: -> { card.account } belongs_to :card, touch: true belongs_to :creator, class_name: "User", default: -> { Current.user } - has_many :reactions, -> { order(:created_at) }, dependent: :delete_all + has_many :reactions, -> { order(:created_at) }, as: :reactable, dependent: :delete_all has_rich_text :body diff --git a/app/models/reaction.rb b/app/models/reaction.rb index 76edf152e..be5fc5d7e 100644 --- a/app/models/reaction.rb +++ b/app/models/reaction.rb @@ -1,6 +1,6 @@ class Reaction < ApplicationRecord - belongs_to :account, default: -> { comment.account } - belongs_to :comment, touch: true + belongs_to :account, default: -> { reactable.account } + belongs_to :reactable, polymorphic: true, touch: true belongs_to :reacter, class_name: "User", default: -> { Current.user } scope :ordered, -> { order(:created_at) } @@ -11,6 +11,6 @@ class Reaction < ApplicationRecord private def register_card_activity - comment.card.touch_last_active_at + reactable.card.touch_last_active_at end end diff --git a/app/views/cards/comments/reactions/_reaction.html.erb b/app/views/cards/comments/reactions/_reaction.html.erb index 2c9dfc01b..da4625880 100644 --- a/app/views/cards/comments/reactions/_reaction.html.erb +++ b/app/views/cards/comments/reactions/_reaction.html.erb @@ -15,7 +15,7 @@ class: [ "txt-small", { "txt-medium": reaction.all_emoji? } ], data: { action: "click->reaction-delete#reveal keydown.enter->reaction-delete#reveal:prevent", reaction_delete_target: "content" } %> - <%= button_to card_comment_reaction_path(reaction.comment.card, reaction.comment, reaction), + <%= button_to card_comment_reaction_path(reaction.reactable.card, reaction.reactable, reaction), method: :delete, class: "reaction__delete btn btn--negative flex-item-justify-end", data: { action: "reaction-delete#perform", reaction_delete_target: "button" } do %> diff --git a/app/views/cards/comments/reactions/_reaction.json.jbuilder b/app/views/cards/comments/reactions/_reaction.json.jbuilder index 17ad70f70..ad50825fb 100644 --- a/app/views/cards/comments/reactions/_reaction.json.jbuilder +++ b/app/views/cards/comments/reactions/_reaction.json.jbuilder @@ -1,5 +1,5 @@ json.cache! reaction do json.(reaction, :id, :content) json.reacter reaction.reacter, partial: "users/user", as: :user - json.url card_comment_reaction_url(reaction.comment.card, reaction.comment, reaction) + json.url card_comment_reaction_url(reaction.reactable.card, reaction.reactable, reaction) end diff --git a/db/migrate/20260121155752_make_reactions_polymorphic.rb b/db/migrate/20260121155752_make_reactions_polymorphic.rb new file mode 100644 index 000000000..6c3d9cac4 --- /dev/null +++ b/db/migrate/20260121155752_make_reactions_polymorphic.rb @@ -0,0 +1,27 @@ +class MakeReactionsPolymorphic < ActiveRecord::Migration[8.0] + def change + add_column :reactions, :reactable_type, :string + add_column :reactions, :reactable_id, :uuid + + reversible do |dir| + dir.up do + execute <<~SQL + UPDATE reactions SET reactable_type = 'Comment', reactable_id = comment_id + SQL + end + + dir.down do + execute <<~SQL + UPDATE reactions SET comment_id = reactable_id WHERE reactable_type = 'Comment' + SQL + end + end + + change_column_null :reactions, :reactable_type, false + change_column_null :reactions, :reactable_id, false + + remove_column :reactions, :comment_id, :uuid + + add_index :reactions, [:reactable_type, :reactable_id] + end +end diff --git a/db/schema.rb b/db/schema.rb index 86b9f2937..fc83e3f58 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.2].define(version: 2025_12_24_092315) do +ActiveRecord::Schema[8.2].define(version: 2026_01_21_155752) do create_table "accesses", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.datetime "accessed_at" t.uuid "account_id", null: false @@ -412,13 +412,14 @@ ActiveRecord::Schema[8.2].define(version: 2025_12_24_092315) do create_table "reactions", id: :uuid, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.uuid "account_id", null: false - t.uuid "comment_id", null: false t.string "content", limit: 16, null: false t.datetime "created_at", null: false + t.uuid "reactable_id", null: false + t.string "reactable_type", null: false t.uuid "reacter_id", null: false t.datetime "updated_at", null: false t.index ["account_id"], name: "index_reactions_on_account_id" - t.index ["comment_id"], name: "index_reactions_on_comment_id" + t.index ["reactable_type", "reactable_id"], name: "index_reactions_on_reactable_type_and_reactable_id" t.index ["reacter_id"], name: "index_reactions_on_reacter_id" end diff --git a/db/schema_sqlite.rb b/db/schema_sqlite.rb index b76f99865..817e37204 100644 --- a/db/schema_sqlite.rb +++ b/db/schema_sqlite.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.2].define(version: 2025_12_24_092315) do +ActiveRecord::Schema[8.2].define(version: 2026_01_21_155752) do create_table "accesses", id: :uuid, force: :cascade do |t| t.datetime "accessed_at" t.uuid "account_id", null: false @@ -412,13 +412,14 @@ ActiveRecord::Schema[8.2].define(version: 2025_12_24_092315) do create_table "reactions", id: :uuid, force: :cascade do |t| t.uuid "account_id", null: false - t.uuid "comment_id", null: false t.string "content", limit: 16, null: false t.datetime "created_at", null: false + t.uuid "reactable_id", null: false + t.string "reactable_type", limit: 255, null: false t.uuid "reacter_id", null: false t.datetime "updated_at", null: false t.index ["account_id"], name: "index_reactions_on_account_id" - t.index ["comment_id"], name: "index_reactions_on_comment_id" + t.index ["reactable_type", "reactable_id"], name: "index_reactions_on_reactable_type_and_reactable_id" t.index ["reacter_id"], name: "index_reactions_on_reacter_id" end diff --git a/test/fixtures/reactions.yml b/test/fixtures/reactions.yml index 16714c601..c505ab076 100644 --- a/test/fixtures/reactions.yml +++ b/test/fixtures/reactions.yml @@ -2,12 +2,12 @@ kevin: id: <%= ActiveRecord::FixtureSet.identify("kevin_reaction", :uuid) %> account: 37s_uuid content: "👍" - comment: logo_agreement_jz_uuid + reactable: logo_agreement_jz_uuid (Comment) reacter: kevin_uuid david: id: <%= ActiveRecord::FixtureSet.identify("david_reaction", :uuid) %> account: 37s_uuid content: "👍" - comment: logo_agreement_jz_uuid + reactable: logo_agreement_jz_uuid (Comment) reacter: david_uuid