diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 37df884..f04e394 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -4,4 +4,30 @@ class GroupsController < ApplicationController def index render json: Groups::SummaryQuery.new.call.as_json end + + def create + group = Group.create!(**group_params, parent:) + render json: group.as_json(only: %i[id name icon color parent_id]), status: :created + end + + def update + group = Group.find(params[:id]) + group.update!(**group_params, parent:) + render json: group.as_json(only: %i[id name icon color parent_id]), status: :ok + end + + def destroy + Group.find(params[:id]).destroy! + render json: {}, status: :ok + end + + private + + def parent + params[:group][:parent_id].present? ? Group.find(params[:group][:parent_id]) : nil + end + + def group_params + params.expect(group: [:name, :icon, :color]) + end end diff --git a/app/models/group.rb b/app/models/group.rb index 5056b28..a00a671 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -38,7 +38,7 @@ class Group < ApplicationRecord scope :roots, -> { where(parent_id: nil) } - has_many :guests + has_many :guests, dependent: :nullify def colorize_children(generation = 1) derived_colors = generation == 1 ? color.paint.palette.analogous(size: children.count) : color.paint.palette.decreasing_saturation diff --git a/app/models/guest.rb b/app/models/guest.rb index 929cc6e..a418a27 100644 --- a/app/models/guest.rb +++ b/app/models/guest.rb @@ -10,7 +10,7 @@ # status :integer default("considered") # created_at :datetime not null # updated_at :datetime not null -# group_id :uuid not null +# group_id :uuid # wedding_id :uuid not null # # Indexes diff --git a/config/routes.rb b/config/routes.rb index bd26594..5b2c031 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,7 +13,7 @@ Rails.application.routes.draw do get '/users/confirmation', to: 'users/confirmations#show', as: :confirmation end - resources :groups, only: :index + resources :groups, only: %i[index create update destroy] resources :guests, only: %i[index create update destroy] do post :bulk_update, on: :collection end diff --git a/db/migrate/20241208102932_allow_ungrouped_guests.rb b/db/migrate/20241208102932_allow_ungrouped_guests.rb new file mode 100644 index 0000000..e4bb19a --- /dev/null +++ b/db/migrate/20241208102932_allow_ungrouped_guests.rb @@ -0,0 +1,5 @@ +class AllowUngroupedGuests < ActiveRecord::Migration[8.0] + def change + change_column_null :guests, :group_id, true + end +end diff --git a/db/schema.rb b/db/schema.rb index 29940a3..e8f6c9f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1,5 +1,3 @@ -# Copyright (C) 2024 Manuel Bustillo - # This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. @@ -12,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_07_112305) do +ActiveRecord::Schema[8.0].define(version: 2024_12_08_102932) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" @@ -48,7 +46,7 @@ ActiveRecord::Schema[8.0].define(version: 2024_12_07_112305) do t.string "phone" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.uuid "group_id", null: false + t.uuid "group_id" t.integer "status", default: 0 t.string "name" t.uuid "wedding_id", null: false diff --git a/spec/requests/groups_spec.rb b/spec/requests/groups_spec.rb index 6d5f057..44f755b 100644 --- a/spec/requests/groups_spec.rb +++ b/spec/requests/groups_spec.rb @@ -31,5 +31,72 @@ RSpec.describe 'groups', type: :request do end regular_api_responses end + + post('create group') do + tags 'Groups' + consumes 'application/json' + produces 'application/json' + parameter Swagger::Schema::SLUG + parameter name: :body, in: :body, schema: { + type: :object, + required: %i[group], + properties: { + group: { + type: :object, + required: %i[name], + properties: Swagger::Schema::GROUP + } + } + } + response(201, 'created') do + schema type: :object, properties: { + id: { type: :string, format: :uuid, required: true }, + **Swagger::Schema::GROUP + } + + xit + end + regular_api_responses + end + + path '/{slug}/groups/{id}' do + put('update group') do + tags 'Groups' + consumes 'application/json' + produces 'application/json' + parameter Swagger::Schema::SLUG + parameter name: :id, in: :path, type: :string, format: :uuid + parameter name: :body, in: :body, schema: { + type: :object, + required: %i[group], + properties: { + group: { + type: :object, + required: %i[name], + properties: Swagger::Schema::GROUP + } + } + } + response(200, 'updated') do + schema type: :object, properties: { + id: { type: :string, format: :uuid, required: true }, + **Swagger::Schema::GROUP + } + + xit + end + regular_api_responses + end + + delete('delete group') do + tags 'Groups' + produces 'application/json' + parameter Swagger::Schema::SLUG + parameter name: :id, in: :path, type: :string, format: :uuid + + response_empty_200 + regular_api_responses + end + end end end diff --git a/spec/requests/schemas.rb b/spec/requests/schemas.rb index e1f7b43..e8e8e9b 100644 --- a/spec/requests/schemas.rb +++ b/spec/requests/schemas.rb @@ -4,10 +4,16 @@ module Swagger module Schema USER = { id: { type: :string, format: :uuid }, - email: { type: :string, format: :email }, - created_at: SwaggerResponseHelper::TIMESTAMP, - updated_at: SwaggerResponseHelper::TIMESTAMP - + email: { type: :string, format: :email }, + created_at: SwaggerResponseHelper::TIMESTAMP, + updated_at: SwaggerResponseHelper::TIMESTAMP + } + + GROUP = { + name: { type: :string }, + icon: { type: :string, example: 'pi pi-crown', description: 'The CSS classes used by the icon' }, + parent_id: { type: :string, format: :uuid }, + color: { type: :string, pattern: '^#(?:[0-9a-fA-F]{3}){1,2}$' } } SLUG = {