diff --git a/app/controllers/tables_arrangements_controller.rb b/app/controllers/tables_arrangements_controller.rb index c09d453..45cf633 100644 --- a/app/controllers/tables_arrangements_controller.rb +++ b/app/controllers/tables_arrangements_controller.rb @@ -4,7 +4,15 @@ class TablesArrangementsController < ApplicationController def index - render json: TablesArrangement.order(discomfort: :asc).limit(3).as_json(only: %i[id name discomfort]) + current_digest = Tables::Distribution.digest(current_tenant) + + render json: TablesArrangement + .order(valid: :desc) + .order(discomfort: :asc) + .select(:id, :name, :discomfort) + .select("digest = '#{current_digest}'::uuid as valid") + .limit(20) + .as_json(only: %i[id name discomfort valid]) end def show @@ -16,6 +24,12 @@ class TablesArrangementsController < ApplicationController .then { |result| render json: { id: params[:id], tables: result } } end + def create + TableSimulatorJob.perform_later(current_tenant.id) + + render json: {}, status: :created + end + private def format(number:, guests:) diff --git a/app/models/guest.rb b/app/models/guest.rb index ad0542f..d080679 100644 --- a/app/models/guest.rb +++ b/app/models/guest.rb @@ -41,16 +41,5 @@ class Guest < ApplicationRecord scope :potential, -> { where.not(status: %i[declined considered]) } - after_destroy :recalculate_simulations - after_save :recalculate_simulations, if: :saved_change_to_status? - has_many :seats, dependent: :delete_all - - private - - def recalculate_simulations - TablesArrangement.delete_all - - ActiveJob.perform_all_later(50.times.map { TableSimulatorJob.new(wedding_id) }) - end end diff --git a/app/models/tables_arrangement.rb b/app/models/tables_arrangement.rb index adece9a..a461555 100644 --- a/app/models/tables_arrangement.rb +++ b/app/models/tables_arrangement.rb @@ -7,6 +7,7 @@ # Table name: tables_arrangements # # id :uuid not null, primary key +# digest :uuid not null # discomfort :integer # name :string not null # created_at :datetime not null diff --git a/app/models/wedding.rb b/app/models/wedding.rb index 83525b5..5f0dabf 100644 --- a/app/models/wedding.rb +++ b/app/models/wedding.rb @@ -19,4 +19,6 @@ class Wedding < ApplicationRecord SLUG_REGEX = /[a-z\d-]+/ validates :slug, presence: true, uniqueness: true, format: { with: /\A#{SLUG_REGEX}\z/ } + + has_many :guests, dependent: :delete_all end diff --git a/app/services/tables/distribution.rb b/app/services/tables/distribution.rb index 87dccb0..cc51308 100644 --- a/app/services/tables/distribution.rb +++ b/app/services/tables/distribution.rb @@ -6,7 +6,13 @@ require_relative '../../extensions/tree_node_extension' module Tables class Distribution - attr_accessor :tables, :min_per_table, :max_per_table + class << self + def digest(wedding) + Digest::UUID.uuid_v5(wedding.id, wedding.guests.potential.order(:id).pluck(:id).join) + end + end + + attr_accessor :tables, :min_per_table, :max_per_table, :hierarchy def initialize(min_per_table:, max_per_table:) @min_per_table = min_per_table @@ -54,7 +60,10 @@ module Tables Seat.insert_all!(records_to_store) - arrangement.update!(discomfort:) + arrangement.update!( + discomfort:, + digest: self.class.digest(tables.first.first.wedding) + ) end end diff --git a/config/routes.rb b/config/routes.rb index f53e7f1..39d0460 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -37,7 +37,7 @@ Rails.application.routes.draw do resources :expenses, only: %i[index create update destroy] do get :summary, on: :collection end - resources :tables_arrangements, only: %i[index show] + resources :tables_arrangements, only: %i[index show create] resources :summary, only: :index root to: redirect("/%{slug}") diff --git a/db/migrate/20250126091823_add_guests_digest_column_to_tables_arrangements.rb b/db/migrate/20250126091823_add_guests_digest_column_to_tables_arrangements.rb new file mode 100644 index 0000000..34a500b --- /dev/null +++ b/db/migrate/20250126091823_add_guests_digest_column_to_tables_arrangements.rb @@ -0,0 +1,5 @@ +class AddGuestsDigestColumnToTablesArrangements < ActiveRecord::Migration[8.0] + def change + add_column :tables_arrangements, :digest, :uuid, null: false, default: 'gen_random_uuid()' + end +end diff --git a/db/schema.rb b/db/schema.rb index 10ab0cd..5b61f3f 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_12_16_231415) do +ActiveRecord::Schema[8.0].define(version: 2025_01_26_091823) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" @@ -206,6 +206,7 @@ ActiveRecord::Schema[8.0].define(version: 2024_12_16_231415) do t.datetime "updated_at", null: false t.string "name", null: false t.uuid "wedding_id", null: false + t.uuid "digest", default: -> { "gen_random_uuid()" }, null: false t.index ["wedding_id"], name: "index_tables_arrangements_on_wedding_id" end diff --git a/spec/requests/tables_arrangements_spec.rb b/spec/requests/tables_arrangements_spec.rb index 4e87cb2..3cc11c1 100644 --- a/spec/requests/tables_arrangements_spec.rb +++ b/spec/requests/tables_arrangements_spec.rb @@ -18,13 +18,27 @@ RSpec.describe 'tables_arrangements' do properties: { id: { type: :string, format: :uuid }, name: { type: :string }, - discomfort: { type: :integer } + discomfort: { type: :integer }, + valid: { type: :boolean } } } xit end regular_api_responses end + + post('create tables arrangement') do + tags 'Tables Arrangements' + produces 'application/json' + parameter Swagger::Schema::SLUG + response(201, 'successful') do + schema type: :object, + required: [], + properties: {} + xit + end + regular_api_responses + end end path '/{slug}/tables_arrangements/{id}' do