diff --git a/lib/templates/create_outboxable_outboxes.rb b/lib/templates/create_outboxable_outboxes.rb new file mode 100644 index 0000000..a37aa85 --- /dev/null +++ b/lib/templates/create_outboxable_outboxes.rb @@ -0,0 +1,25 @@ +class CreateOutboxableOutboxes < ActiveRecord::Migration[7.0] + def change + enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto') + + create_table :outboxes, id: :uuid, default: 'gen_random_uuid()' do |t| + t.integer :status, null: false, default: 0 + + t.string :exchange, null: false, default: '' + t.string :routing_key, null: false, default: '' + + t.integer :attempts, null: false, default: 0 + t.datetime :last_attempted_at, null: true + t.datetime :retry_at, null: true + + t.jsonb :payload, default: {} + t.jsonb :headers, default: {} + + t.integer :size, null: false, default: 0 + + t.references :outboxable, polymorphic: true, null: true + + t.timestamps + end + end +end diff --git a/lib/templates/outbox.rb b/lib/templates/outbox.rb new file mode 100644 index 0000000..af428ca --- /dev/null +++ b/lib/templates/outbox.rb @@ -0,0 +1,32 @@ +class Outbox < ApplicationRecord + attribute :allow_publish, :boolean, default: true + + # Callbacks + after_commit :publish, if: :allow_publish? + before_save :check_publishing + + # Enums + enum status: { pending: 0, published: 1, failed: 2 } + enum size: { single: 0, batch: 1 } + + # Validations + validates :payload, presence: true + validates :exchange, presence: true + validates :routing_key, presence: true + + # Associations + belongs_to :outboxable, polymorphic: true, optional: true + + def increment_attempt + self.attempts = attempts + 1 + self.last_attempted_at = Time.zone.now + end + + def publish + Outboxable::Worker.perform_async(id) + end + + def check_publishing + self.allow_publish = false if published? + end +end \ No newline at end of file