diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 301f7f498..83fbb1e80 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -2,7 +2,7 @@ class CommentsController < ApplicationController include BubbleScoped, BucketScoped def create - @bubble.comments.create! params.expect(comment: [ :body ]) + @bubble.comment params.require(:comment).expect(:body) redirect_to @bubble end end diff --git a/app/models/bubble.rb b/app/models/bubble.rb index b23cd48f2..7b4856aa1 100644 --- a/app/models/bubble.rb +++ b/app/models/bubble.rb @@ -1,5 +1,6 @@ class Bubble < ApplicationRecord - include Assignable, Boostable, Colored, Commentable, Eventable, Messages, Poppable, Searchable, Staged, Taggable + include Assignable, Boostable, Colored, Messages, Poppable, Searchable, Staged, Taggable + include Commentable, Eventable # depend on Messages belongs_to :bucket belongs_to :creator, class_name: "User", default: -> { Current.user } diff --git a/app/models/bubble/commentable.rb b/app/models/bubble/commentable.rb index 1fdc9b13f..8a3106b18 100644 --- a/app/models/bubble/commentable.rb +++ b/app/models/bubble/commentable.rb @@ -2,8 +2,13 @@ module Bubble::Commentable extend ActiveSupport::Concern included do - has_many :comments, dependent: :destroy + has_many :comment_messages, -> { comments }, class_name: "Message" + has_many :comments, through: :comment_messages, source: :messageable, source_type: "Comment" - scope :ordered_by_comments, -> { left_joins(:comments).group(:id).order("COUNT(comments.id) DESC") } + scope :ordered_by_comments, -> { left_joins(:comment_messages).group(:id).order("COUNT(messages.id) DESC") } + end + + def comment(body) + capture Comment.new(body: body) end end diff --git a/app/models/bubble/eventable.rb b/app/models/bubble/eventable.rb index 9d7db3453..c7dadfc3d 100644 --- a/app/models/bubble/eventable.rb +++ b/app/models/bubble/eventable.rb @@ -2,13 +2,20 @@ module Bubble::Eventable extend ActiveSupport::Concern included do - has_many :events, dependent: :delete_all + has_many :event_summary_messages, -> { event_summaries }, class_name: "Message" + has_many :event_summaries, through: :event_summary_messages, source: :messageable, source_type: "EventSummary" after_create -> { track_event :created } end private def track_event(action, creator: Current.user, **particulars) - events.create! action: action, creator: creator, summary: latest_event_summary, particulars: particulars + transaction do + find_or_create_next_summary.events << Event.new(action: action, creator: creator, particulars: particulars) + end + end + + def find_or_create_next_summary + messages.last&.event_summary || capture(event_summaries.build).messageable end end diff --git a/app/models/bubble/messages.rb b/app/models/bubble/messages.rb index 9cfe390c0..552f2f483 100644 --- a/app/models/bubble/messages.rb +++ b/app/models/bubble/messages.rb @@ -5,7 +5,7 @@ module Bubble::Messages has_many :messages, -> { chronologically }, dependent: :destroy end - def latest_event_summary - messages.last&.event_summary || EventSummary.new(bubble: self) + def capture(messageable) + messages.create! messageable: messageable end end diff --git a/app/models/comment.rb b/app/models/comment.rb index e3cfb9e85..4a9afb28b 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -1,7 +1,6 @@ class Comment < ApplicationRecord include Searchable, Messageable - belongs_to :bubble, touch: true belongs_to :creator, class_name: "User", default: -> { Current.user } searchable_by :body, using: :comments_search_index diff --git a/app/models/concerns/messageable.rb b/app/models/concerns/messageable.rb index d8bd1c631..1005f5492 100644 --- a/app/models/concerns/messageable.rb +++ b/app/models/concerns/messageable.rb @@ -5,7 +5,6 @@ module Messageable included do has_one :message, as: :messageable, touch: true - - after_create -> { create_message! bubble: bubble } + has_one :bubble, through: :message end end diff --git a/app/models/event.rb b/app/models/event.rb index 95977dada..006e25ed0 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -2,7 +2,6 @@ class Event < ApplicationRecord include Assignments, Stages belongs_to :creator, class_name: "User" - belongs_to :bubble, touch: true belongs_to :summary, touch: true, class_name: "EventSummary" has_one :account, through: :creator diff --git a/app/models/event_summary.rb b/app/models/event_summary.rb index 530bd2d00..a6b1dbc0d 100644 --- a/app/models/event_summary.rb +++ b/app/models/event_summary.rb @@ -1,8 +1,6 @@ class EventSummary < ApplicationRecord include Messageable - attr_accessor :bubble - has_many :events, -> { chronologically }, dependent: :delete_all, inverse_of: :summary do def grouped_boosts boosts.group_by(&:creator) diff --git a/db/migrate/20241022180133_add_summary_reference_to_events.rb b/db/migrate/20241022180133_add_summary_reference_to_events.rb index d15387eef..411e6c94e 100644 --- a/db/migrate/20241022180133_add_summary_reference_to_events.rb +++ b/db/migrate/20241022180133_add_summary_reference_to_events.rb @@ -1,8 +1,9 @@ class AddSummaryReferenceToEvents < ActiveRecord::Migration[8.0] def change add_reference :events, :summary, foreign_key: { to_table: :event_summaries }, index: false - remove_index :events, %i[ bubble_id action ] - add_index :events, :bubble_id add_index :events, %i[ summary_id action ] + + remove_index :events, %i[ bubble_id action ] + remove_column :events, :bubble_id, :references, null: false, index: false end end diff --git a/db/migrate/20241025224942_remove_bubble_reference_from_comments.rb b/db/migrate/20241025224942_remove_bubble_reference_from_comments.rb new file mode 100644 index 000000000..f99c189a5 --- /dev/null +++ b/db/migrate/20241025224942_remove_bubble_reference_from_comments.rb @@ -0,0 +1,5 @@ +class RemoveBubbleReferenceFromComments < ActiveRecord::Migration[8.0] + def change + remove_column :comments, :bubble_id, :references, null: false, index: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 3db72af4c..1f1a6151f 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.0].define(version: 2024_10_22_180133) do +ActiveRecord::Schema[8.0].define(version: 2024_10_25_224942) do create_table "accesses", force: :cascade do |t| t.integer "bucket_id", null: false t.integer "user_id", null: false @@ -105,7 +105,6 @@ ActiveRecord::Schema[8.0].define(version: 2024_10_22_180133) do create_table "comments", force: :cascade do |t| t.text "body", null: false t.integer "creator_id", null: false - t.integer "bubble_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false end @@ -116,14 +115,12 @@ ActiveRecord::Schema[8.0].define(version: 2024_10_22_180133) do end create_table "events", force: :cascade do |t| - t.integer "bubble_id", null: false t.integer "creator_id", null: false t.json "particulars", default: {} t.string "action", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "summary_id" - t.index ["bubble_id"], name: "index_events_on_bubble_id" t.index ["creator_id"], name: "index_events_on_creator_id" t.index ["summary_id", "action"], name: "index_events_on_summary_id_and_action" end diff --git a/test/fixtures/comments.yml b/test/fixtures/comments.yml index f0abd276c..3f988f427 100644 --- a/test/fixtures/comments.yml +++ b/test/fixtures/comments.yml @@ -1,16 +1,13 @@ logo_agreement_jz: body: I agree. creator: jz - bubble: logo created_at: <%= 2.days.ago %> logo_agreement_kevin: body: Same, let’s do it. creator: kevin - bubble: logo created_at: <%= 2.hours.ago %> layout_overflowing_david: body: The text is overflowing the container. creator: david - bubble: layout diff --git a/test/fixtures/events.yml b/test/fixtures/events.yml index 2dd93640f..d6be1dbe1 100644 --- a/test/fixtures/events.yml +++ b/test/fixtures/events.yml @@ -1,13 +1,11 @@ logo_created: creator: david - bubble: logo action: created summary: logo_initial_activity created_at: <%= 1.week.ago %> logo_assignment_jz: creator: david - bubble: logo action: assigned summary: logo_initial_activity particulars: <%= { assignee_ids: [ ActiveRecord::FixtureSet.identify(:jz) ] }.to_json %> @@ -15,14 +13,12 @@ logo_assignment_jz: logo_boost_dhh: creator: david - bubble: logo action: boosted summary: logo_initial_activity created_at: <%= 1.week.ago + 2.hours %> logo_assignment_km: creator: david - bubble: logo action: assigned summary: logo_second_activity particulars: <%= { assignee_ids: [ ActiveRecord::FixtureSet.identify(:kevin) ] }.to_json %> @@ -30,42 +26,36 @@ logo_assignment_km: logo_boost_km1: creator: kevin - bubble: logo action: boosted summary: logo_second_activity created_at: <%= 1.day.ago + 1.hour %> logo_boost_km2: creator: kevin - bubble: logo action: boosted summary: logo_second_activity created_at: <%= 1.day.ago + 2.hours %> logo_boost_jz1: creator: jz - bubble: logo action: boosted summary: logo_second_activity created_at: <%= 1.day.ago + 3.hours %> logo_boost_jz2: creator: jz - bubble: logo action: boosted summary: logo_third_activity created_at: <%= 1.hour.ago %> layout_created: creator: david - bubble: layout action: created summary: layout_initial_activity created_at: <%= 1.week.ago %> layout_assignment_jz: creator: david - bubble: layout action: assigned summary: layout_initial_activity particulars: <%= { assignee_ids: [ ActiveRecord::FixtureSet.identify(:jz) ] }.to_json %> @@ -73,14 +63,12 @@ layout_assignment_jz: text_created: creator: kevin - bubble: text action: created summary: text_initial_activity created_at: <%= 1.week.ago %> shipping_created: creator: kevin - bubble: shipping action: created summary: shipping_initial_activity created_at: <%= 1.week.ago %>