From 142f06b96961e84f48925709794150c983868259 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Mon, 5 Aug 2024 10:06:43 +0000 Subject: [PATCH 01/16] Update dependency bootsnap to v1.18.4 --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0e31210..969a923 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -80,7 +80,7 @@ GEM base64 (0.2.0) bigdecimal (3.1.8) bindex (0.8.1) - bootsnap (1.18.3) + bootsnap (1.18.4) msgpack (~> 1.2) builder (3.3.0) coderay (1.1.3) From 56852a81091ad692efe691c63ab7e22fa42cc33f Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Fri, 9 Aug 2024 20:15:41 +0200 Subject: [PATCH 02/16] Remove dangling containers after failed execution --- .github/workflows/tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index eefea88..e4d4fec 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -35,3 +35,6 @@ jobs: env: RAILS_ENV: test DATABASE_URL: postgres://postgres:postgres@postgres:5432/postgres + - name: Clean up containers generated by this flow + if: failure() + run: docker ps --filter network=$JOB_CONTAINER_NAME-$GITHUB_JOB-network --filter name=$JOB_CONTAINER_NAME-* --format "{{.ID}}" | xargs docker rm -f From 32d796aa3038bf40eebf3ff15b1b30ac2569c3c9 Mon Sep 17 00:00:00 2001 From: bustikiller Date: Sat, 10 Aug 2024 08:28:09 +0000 Subject: [PATCH 03/16] Update renovate.json --- renovate.json | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/renovate.json b/renovate.json index 7190a60..aebcb03 100644 --- a/renovate.json +++ b/renovate.json @@ -1,3 +1,11 @@ { - "$schema": "https://docs.renovatebot.com/renovate-schema.json" -} + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "labels": ["dependencies"], + "packageRules": [ + { + "matchUpdateTypes": ["minor", "patch"], + "matchCurrentVersion": "!/^0/", + "automerge": true + } + ] +} \ No newline at end of file From bab0aacadc579205bd44adc03245a1599ce373b3 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 10 Aug 2024 18:02:38 +0000 Subject: [PATCH 04/16] Update dependency rspec-rails to v6.1.3 --- Gemfile | 1 + Gemfile.lock | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 3c61f52..2f2abee 100644 --- a/Gemfile +++ b/Gemfile @@ -68,3 +68,4 @@ gem "money" gem 'acts-as-taggable-on' gem "rubytree" +gem 'react-rails' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 969a923..d23deb5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -77,6 +77,10 @@ GEM tzinfo (~> 2.0) acts-as-taggable-on (10.0.0) activerecord (>= 6.1, < 7.2) + babel-source (5.8.35) + babel-transpiler (0.7.0) + babel-source (>= 4.0, < 6) + execjs (~> 2.0) base64 (0.2.0) bigdecimal (3.1.8) bindex (0.8.1) @@ -84,7 +88,7 @@ GEM msgpack (~> 1.2) builder (3.3.0) coderay (1.1.3) - concurrent-ruby (1.3.3) + concurrent-ruby (1.3.4) connection_pool (2.4.1) crass (1.0.6) date (3.3.4) @@ -94,6 +98,7 @@ GEM diff-lcs (1.5.1) drb (2.2.1) erubi (1.13.0) + execjs (2.9.1) factory_bot (6.4.6) activesupport (>= 5.0.0) factory_bot_rails (6.4.3) @@ -204,6 +209,12 @@ GEM rake (13.2.1) rdoc (6.7.0) psych (>= 4.0.0) + react-rails (3.2.1) + babel-transpiler (>= 0.7.0) + connection_pool + execjs + railties (>= 3.2) + tilt redis (5.2.0) redis-client (>= 0.22.0) redis-client (0.22.2) @@ -240,6 +251,7 @@ GEM railties (>= 6.0.0) stringio (3.1.1) thor (1.3.1) + tilt (2.4.0) timeout (0.4.1) turbo-rails (2.0.6) actionpack (>= 6.0.0) @@ -279,6 +291,7 @@ DEPENDENCIES pry puma (>= 5.0) rails (~> 7.1.3, >= 7.1.3.2) + react-rails redis (>= 4.0.1) rspec-rails (~> 6.1.0) rubytree From 716b819de29cac7ba269173bfc204527c019d669 Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Sun, 11 Aug 2024 16:19:54 +0200 Subject: [PATCH 05/16] Use jsonapi-rails to serialize API responses --- Gemfile | 4 +++- Gemfile.lock | 15 +++++++++++++++ app/controllers/guests_controller.rb | 5 +++++ app/serializers/serializable_guest.rb | 9 +++++++++ config/initializers/cors.rb | 8 ++++++++ 5 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 app/serializers/serializable_guest.rb create mode 100644 config/initializers/cors.rb diff --git a/Gemfile b/Gemfile index 2f2abee..6bcb96a 100644 --- a/Gemfile +++ b/Gemfile @@ -68,4 +68,6 @@ gem "money" gem 'acts-as-taggable-on' gem "rubytree" -gem 'react-rails' \ No newline at end of file +gem 'react-rails' +gem 'rack-cors' +gem 'jsonapi-rails' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index d23deb5..90dbe8c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -122,6 +122,17 @@ GEM actionview (>= 5.0.0) activesupport (>= 5.0.0) json (2.7.2) + jsonapi-deserializable (0.2.0) + jsonapi-parser (0.1.1) + jsonapi-rails (0.4.1) + jsonapi-parser (~> 0.1.0) + jsonapi-rb (~> 0.5.0) + jsonapi-rb (0.5.0) + jsonapi-deserializable (~> 0.2.0) + jsonapi-serializable (~> 0.3.0) + jsonapi-renderer (0.2.2) + jsonapi-serializable (0.3.1) + jsonapi-renderer (~> 0.2.0) loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) @@ -170,6 +181,8 @@ GEM nio4r (~> 2.0) racc (1.8.1) rack (3.1.7) + rack-cors (2.0.2) + rack (>= 2.0.0) rack-session (2.0.0) rack (>= 3.0.0) rack-test (2.1.0) @@ -286,10 +299,12 @@ DEPENDENCIES faker importmap-rails jbuilder + jsonapi-rails money pg (~> 1.1) pry puma (>= 5.0) + rack-cors rails (~> 7.1.3, >= 7.1.3.2) react-rails redis (>= 4.0.1) diff --git a/app/controllers/guests_controller.rb b/app/controllers/guests_controller.rb index 72baf50..77298d6 100644 --- a/app/controllers/guests_controller.rb +++ b/app/controllers/guests_controller.rb @@ -9,6 +9,11 @@ class GuestsController < ApplicationController .left_outer_joins(:affinity_groups) .order('tags.name' => :asc) .includes(:affinity_groups, :unbreakable_bonds) + + respond_to do |format| + format.html + format.json { render jsonapi: @guests } + end end # GET /guests/1 or /guests/1.json diff --git a/app/serializers/serializable_guest.rb b/app/serializers/serializable_guest.rb new file mode 100644 index 0000000..c1e4bcc --- /dev/null +++ b/app/serializers/serializable_guest.rb @@ -0,0 +1,9 @@ +class SerializableGuest < JSONAPI::Serializable::Resource + type 'guest' + + attributes :id, :email + + attribute :name do + "#{@object.first_name} #{@object.last_name}" + end +end diff --git a/config/initializers/cors.rb b/config/initializers/cors.rb new file mode 100644 index 0000000..a908920 --- /dev/null +++ b/config/initializers/cors.rb @@ -0,0 +1,8 @@ +# config/initializers/cors.rb + +Rails.application.config.middleware.insert_before 0, Rack::Cors do + allow do + origins '*' + resource '*', headers: :any, methods: [:get, :post, :patch, :put, :delete] + end + end \ No newline at end of file From 3bc7a0c58b9c882af9b1707a7623501413865c6d Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Sun, 11 Aug 2024 16:29:10 +0200 Subject: [PATCH 06/16] Create model and controller --- app/controllers/groups_controller.rb | 5 +++++ app/helpers/groups_helper.rb | 2 ++ app/models/group.rb | 4 ++++ app/serializers/serializable_group.rb | 5 +++++ config/routes.rb | 1 + db/migrate/20240811142121_create_groups.rb | 13 +++++++++++++ db/schema.rb | 11 ++++++++++- db/seeds.rb | 2 ++ spec/factories/groups.rb | 7 +++++++ spec/models/group_spec.rb | 5 +++++ 10 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 app/controllers/groups_controller.rb create mode 100644 app/helpers/groups_helper.rb create mode 100644 app/models/group.rb create mode 100644 app/serializers/serializable_group.rb create mode 100644 db/migrate/20240811142121_create_groups.rb create mode 100644 spec/factories/groups.rb create mode 100644 spec/models/group_spec.rb diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb new file mode 100644 index 0000000..3a0b9c9 --- /dev/null +++ b/app/controllers/groups_controller.rb @@ -0,0 +1,5 @@ +class GroupsController < ApplicationController + def index + render jsonapi: Group.all + end +end diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb new file mode 100644 index 0000000..c091b2f --- /dev/null +++ b/app/helpers/groups_helper.rb @@ -0,0 +1,2 @@ +module GroupsHelper +end diff --git a/app/models/group.rb b/app/models/group.rb new file mode 100644 index 0000000..6d753b8 --- /dev/null +++ b/app/models/group.rb @@ -0,0 +1,4 @@ +class Group < ApplicationRecord + validates :name, uniqueness: true + validates :name, :order, presence: true +end diff --git a/app/serializers/serializable_group.rb b/app/serializers/serializable_group.rb new file mode 100644 index 0000000..5c3eec5 --- /dev/null +++ b/app/serializers/serializable_group.rb @@ -0,0 +1,5 @@ +class SerializableGroup < JSONAPI::Serializable::Resource + type 'group' + + attributes :name, :icon +end diff --git a/config/routes.rb b/config/routes.rb index 67f091d..6e4d17b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + resources :groups, only: :index resources :guests do post :import, on: :collection end diff --git a/db/migrate/20240811142121_create_groups.rb b/db/migrate/20240811142121_create_groups.rb new file mode 100644 index 0000000..0246978 --- /dev/null +++ b/db/migrate/20240811142121_create_groups.rb @@ -0,0 +1,13 @@ +class CreateGroups < ActiveRecord::Migration[7.1] + def change + create_table :groups, id: :uuid do |t| + t.string :name, null: false + t.string :icon + t.integer :order, null: false, default: 1 + + t.timestamps + end + + add_index :groups, :name, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 08c4026..a3a2de8 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[7.1].define(version: 2024_07_24_181853) do +ActiveRecord::Schema[7.1].define(version: 2024_08_11_142121) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -26,6 +26,15 @@ ActiveRecord::Schema[7.1].define(version: 2024_07_24_181853) do t.datetime "updated_at", null: false end + create_table "groups", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.string "name", null: false + t.string "icon" + t.integer "order", default: 1, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "index_groups_on_name", unique: true + end + create_table "guests", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.string "first_name" t.string "last_name" diff --git a/db/seeds.rb b/db/seeds.rb index 162a80f..67a32b9 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -5,6 +5,7 @@ Expense.delete_all Guest.delete_all ActsAsTaggableOn::Tagging.delete_all ActsAsTaggableOn::Tag.delete_all +Group.delete_all Expense.create!(name: 'Photographer', amount: 3000, pricing_type: 'fixed') Expense.create!(name: 'Country house', amount: 6000, pricing_type: 'fixed') @@ -43,6 +44,7 @@ samples = { football_team_a: 15, dance_club: 10 }.each_with_object([]) do |(affinity_group, count), acc| + Group.find_or_create_by!(name: affinity_group.to_s.humanize) count.times { acc << affinity_group } end diff --git a/spec/factories/groups.rb b/spec/factories/groups.rb new file mode 100644 index 0000000..a8fe677 --- /dev/null +++ b/spec/factories/groups.rb @@ -0,0 +1,7 @@ +FactoryBot.define do + factory :group do + name { "MyString" } + icon { "MyString" } + order { 1 } + end +end diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb new file mode 100644 index 0000000..be100cf --- /dev/null +++ b/spec/models/group_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Group, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end From cc45b4c16e086e00a8ec750cc675867360746e1a Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Sun, 11 Aug 2024 17:26:43 +0200 Subject: [PATCH 07/16] Define a hierarchy of groups --- app/controllers/groups_controller.rb | 2 +- app/models/group.rb | 3 ++ app/serializers/serializable_group.rb | 2 ++ .../20240811143801_add_parent_to_group.rb | 5 ++++ db/schema.rb | 5 +++- db/seeds.rb | 30 ++++++++++++++++++- 6 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20240811143801_add_parent_to_group.rb diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 3a0b9c9..461a67f 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -1,5 +1,5 @@ class GroupsController < ApplicationController def index - render jsonapi: Group.all + render jsonapi: Group.where(parent_id: nil), include: [children: [children: [:children]]] end end diff --git a/app/models/group.rb b/app/models/group.rb index 6d753b8..5a2e844 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -1,4 +1,7 @@ class Group < ApplicationRecord validates :name, uniqueness: true validates :name, :order, presence: true + + has_many :children, class_name: 'Group', foreign_key: 'parent_id' + belongs_to :parent, class_name: 'Group', optional: true end diff --git a/app/serializers/serializable_group.rb b/app/serializers/serializable_group.rb index 5c3eec5..e90dc52 100644 --- a/app/serializers/serializable_group.rb +++ b/app/serializers/serializable_group.rb @@ -2,4 +2,6 @@ class SerializableGroup < JSONAPI::Serializable::Resource type 'group' attributes :name, :icon + + has_many :children end diff --git a/db/migrate/20240811143801_add_parent_to_group.rb b/db/migrate/20240811143801_add_parent_to_group.rb new file mode 100644 index 0000000..575af38 --- /dev/null +++ b/db/migrate/20240811143801_add_parent_to_group.rb @@ -0,0 +1,5 @@ +class AddParentToGroup < ActiveRecord::Migration[7.1] + def change + add_reference :groups, :parent, type: :uuid, index: true, foreign_key: { to_table: :groups } + end +end diff --git a/db/schema.rb b/db/schema.rb index a3a2de8..00b4b60 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[7.1].define(version: 2024_08_11_142121) do +ActiveRecord::Schema[7.1].define(version: 2024_08_11_143801) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -32,7 +32,9 @@ ActiveRecord::Schema[7.1].define(version: 2024_08_11_142121) do t.integer "order", default: 1, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.uuid "parent_id" t.index ["name"], name: "index_groups_on_name", unique: true + t.index ["parent_id"], name: "index_groups_on_parent_id" end create_table "guests", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| @@ -91,6 +93,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_08_11_142121) do t.index ["name"], name: "index_tags_on_name", unique: true end + add_foreign_key "groups", "groups", column: "parent_id" add_foreign_key "seats", "guests" add_foreign_key "seats", "tables_arrangements", on_delete: :cascade add_foreign_key "taggings", "tags" diff --git a/db/seeds.rb b/db/seeds.rb index 67a32b9..5103a7d 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -22,6 +22,35 @@ Expense.create!(name: 'Transportation', amount: 3000, pricing_type: 'fixed') Expense.create!(name: 'Invitations', amount: 200, pricing_type: 'fixed') Expense.create!(name: 'Cake', amount: 500, pricing_type: 'fixed') +Group.create!(name: "Jim's guests", icon: "pi pi-heart").tap do |parent| + parent.children.create!(name: "Jim's family", icon: "pi pi-users").tap do |family| + family.children.create!(name: "Jim's close family", icon: "pi pi-home") + family.children.create!(name: "Jim's cousins", icon: "pi pi-home") + family.children.create!(name: "Jim's relatives", icon: "pi pi-home") + end + parent.children.create!(name: "Jim's friends", icon: "pi pi-bullseye") + parent.children.create!(name: "Jim's work", icon: "pi pi-desktop").tap do |work| + work.children.create!(name: "Jim's besties at work", icon: "pi pi-briefcase") + end +end + +Group.create!(name: "Pam's guests", icon: "pi pi-heart-fill").tap do |parent| + parent.children.create!(name: "Pam's family", icon: "pi pi-users").tap do |family| + family.children.create!(name: "Pam's close family", icon: "pi pi-home") + family.children.create!(name: "Pam's cousins", icon: "pi pi-home") + family.children.create!(name: "Pam's relatives", icon: "pi pi-home") + end + parent.children.create!(name: "Pam's friends", icon: "pi pi-bullseye") + parent.children.create!(name: "Pam's work", icon: "pi pi-desktop").tap do |work| + work.children.create!(name: "Pam's besties at work", icon: "pi pi-briefcase") + end +end + +Group.create!(name: "Common guests", icon: "pi pi-users").tap do |parent| + parent.children.create!(name: "College friends", icon: "pi pi-calculator") + parent.children.create!(name: "High school friends", icon: "pi pi-crown") + parent.children.create!(name: "Childhood friends", icon: "pi pi-envelope") +end samples = { close_family_a: 10, @@ -44,7 +73,6 @@ samples = { football_team_a: 15, dance_club: 10 }.each_with_object([]) do |(affinity_group, count), acc| - Group.find_or_create_by!(name: affinity_group.to_s.humanize) count.times { acc << affinity_group } end From b18f526c7821ec194d490de4d0b3fa050f0a3768 Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Sun, 11 Aug 2024 17:47:32 +0200 Subject: [PATCH 08/16] Add rubocop as dev dependency --- Gemfile | 87 +++++++++++++++------------------------------------- Gemfile.lock | 25 +++++++++++++++ 2 files changed, 49 insertions(+), 63 deletions(-) diff --git a/Gemfile b/Gemfile index 6bcb96a..bea2d7b 100644 --- a/Gemfile +++ b/Gemfile @@ -1,73 +1,34 @@ -source "https://rubygems.org" +source 'https://rubygems.org' -ruby "3.3.4" +ruby '3.3.4' +gem 'acts-as-taggable-on' +gem 'bootsnap', require: false +gem 'importmap-rails' +gem 'jbuilder' +gem 'money' +gem 'pg', '~> 1.1' +gem 'puma', '>= 5.0' +gem 'rails', '~> 7.1.3', '>= 7.1.3.2' +gem 'redis', '>= 4.0.1' +gem 'sprockets-rails' +gem 'stimulus-rails' +gem 'turbo-rails' +gem 'tzinfo-data', platforms: %i[windows jruby] -# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" -gem "rails", "~> 7.1.3", ">= 7.1.3.2" - -# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails] -gem "sprockets-rails" - -# Use postgresql as the database for Active Record -gem "pg", "~> 1.1" - -# Use the Puma web server [https://github.com/puma/puma] -gem "puma", ">= 5.0" - -# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] -gem "importmap-rails" - -# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] -gem "turbo-rails" - -# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] -gem "stimulus-rails" - -# Build JSON APIs with ease [https://github.com/rails/jbuilder] -gem "jbuilder" - -# Use Redis adapter to run Action Cable in production -gem "redis", ">= 4.0.1" - -# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis] -# gem "kredis" - -# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] -# gem "bcrypt", "~> 3.1.7" - -# Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem "tzinfo-data", platforms: %i[ windows jruby ] - -# Reduces boot times through caching; required in config/boot.rb -gem "bootsnap", require: false - -# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] -# gem "image_processing", "~> 1.2" +gem 'jsonapi-rails' +gem 'rack-cors' +gem 'react-rails' +gem 'rubytree' group :development, :test do - # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem - gem "debug", platforms: %i[ mri windows ] - gem 'rspec-rails', '~> 6.1.0' + gem 'debug', platforms: %i[mri windows] + gem 'factory_bot_rails' gem 'faker' gem 'pry' - gem "factory_bot_rails" + gem 'rspec-rails', '~> 6.1.0' end group :development do - # Use console on exceptions pages [https://github.com/rails/web-console] - gem "web-console" - - # Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler] - # gem "rack-mini-profiler" - - # Speed up commands on slow machines / big apps [https://github.com/rails/spring] - # gem "spring" + gem 'rubocop' + gem 'web-console' end - -gem "money" -gem 'acts-as-taggable-on' - -gem "rubytree" -gem 'react-rails' -gem 'rack-cors' -gem 'jsonapi-rails' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 90dbe8c..0e23ca2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -77,6 +77,7 @@ GEM tzinfo (~> 2.0) acts-as-taggable-on (10.0.0) activerecord (>= 6.1, < 7.2) + ast (2.4.2) babel-source (5.8.35) babel-transpiler (0.7.0) babel-source (>= 4.0, < 6) @@ -133,6 +134,7 @@ GEM jsonapi-renderer (0.2.2) jsonapi-serializable (0.3.1) jsonapi-renderer (~> 0.2.0) + language_server-protocol (3.17.0.3) loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) @@ -171,6 +173,10 @@ GEM racc (~> 1.4) nokogiri (1.16.7-x86_64-linux) racc (~> 1.4) + parallel (1.26.2) + parser (3.3.4.2) + ast (~> 2.4.1) + racc pg (1.5.7) pry (0.14.2) coderay (~> 1.1) @@ -219,6 +225,7 @@ GEM rake (>= 12.2) thor (~> 1.0, >= 1.2.2) zeitwerk (~> 2.6) + rainbow (3.1.1) rake (13.2.1) rdoc (6.7.0) psych (>= 4.0.0) @@ -232,8 +239,10 @@ GEM redis-client (>= 0.22.0) redis-client (0.22.2) connection_pool + regexp_parser (2.9.2) reline (0.5.9) io-console (~> 0.5) + rexml (3.2.8) rspec-core (3.12.3) rspec-support (~> 3.12.0) rspec-expectations (3.12.4) @@ -251,6 +260,20 @@ GEM rspec-mocks (~> 3.12) rspec-support (~> 3.12) rspec-support (3.12.2) + rubocop (1.65.1) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.4, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.31.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.32.0) + parser (>= 3.3.1.0) + ruby-progressbar (1.13.0) rubytree (2.0.3) json (~> 2.0, > 2.3.1) sprockets (4.2.1) @@ -272,6 +295,7 @@ GEM railties (>= 6.0.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) + unicode-display_width (2.5.0) web-console (4.2.1) actionview (>= 6.0.0) activemodel (>= 6.0.0) @@ -309,6 +333,7 @@ DEPENDENCIES react-rails redis (>= 4.0.1) rspec-rails (~> 6.1.0) + rubocop rubytree sprockets-rails stimulus-rails From cca869a0c4e304ff2063a5aae1837c16483f69ca Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Sun, 11 Aug 2024 18:25:12 +0200 Subject: [PATCH 09/16] Display group name in the list of guests --- app/controllers/guests_controller.rb | 10 +- app/models/group.rb | 10 +- app/models/guest.rb | 2 +- app/serializers/serializable_guest.rb | 6 +- .../20240811154115_add_group_to_guest.rb | 5 + db/schema.rb | 5 +- db/seeds.rb | 100 ++++++------------ 7 files changed, 55 insertions(+), 83 deletions(-) create mode 100644 db/migrate/20240811154115_add_group_to_guest.rb diff --git a/app/controllers/guests_controller.rb b/app/controllers/guests_controller.rb index 77298d6..925770f 100644 --- a/app/controllers/guests_controller.rb +++ b/app/controllers/guests_controller.rb @@ -6,14 +6,10 @@ class GuestsController < ApplicationController # GET /guests or /guests.json def index @guests = Guest.all - .left_outer_joins(:affinity_groups) - .order('tags.name' => :asc) - .includes(:affinity_groups, :unbreakable_bonds) + .joins(:group) + .order('groups.name' => :asc) - respond_to do |format| - format.html - format.json { render jsonapi: @guests } - end + render jsonapi: @guests end # GET /guests/1 or /guests/1.json diff --git a/app/models/group.rb b/app/models/group.rb index 5a2e844..afcadaa 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -1,7 +1,9 @@ class Group < ApplicationRecord - validates :name, uniqueness: true - validates :name, :order, presence: true + validates :name, uniqueness: true + validates :name, :order, presence: true - has_many :children, class_name: 'Group', foreign_key: 'parent_id' - belongs_to :parent, class_name: 'Group', optional: true + has_many :children, class_name: 'Group', foreign_key: 'parent_id' + belongs_to :parent, class_name: 'Group', optional: true + + has_many :guests end diff --git a/app/models/guest.rb b/app/models/guest.rb index 60e3bc2..927a589 100644 --- a/app/models/guest.rb +++ b/app/models/guest.rb @@ -1,6 +1,6 @@ class Guest < ApplicationRecord acts_as_taggable_on :affinity_groups, :unbreakable_bonds - + belongs_to :group def full_name "#{first_name} #{last_name}" end diff --git a/app/serializers/serializable_guest.rb b/app/serializers/serializable_guest.rb index c1e4bcc..3311d8b 100644 --- a/app/serializers/serializable_guest.rb +++ b/app/serializers/serializable_guest.rb @@ -1,9 +1,13 @@ class SerializableGuest < JSONAPI::Serializable::Resource type 'guest' - attributes :id, :email + attributes :id, :email, :group_id attribute :name do "#{@object.first_name} #{@object.last_name}" end + + attribute :group_name do + @object.group.name + end end diff --git a/db/migrate/20240811154115_add_group_to_guest.rb b/db/migrate/20240811154115_add_group_to_guest.rb new file mode 100644 index 0000000..d4e2bd4 --- /dev/null +++ b/db/migrate/20240811154115_add_group_to_guest.rb @@ -0,0 +1,5 @@ +class AddGroupToGuest < ActiveRecord::Migration[7.1] + def change + add_reference :guests, :group, null: false, foreign_key: true, type: :uuid + end +end diff --git a/db/schema.rb b/db/schema.rb index 00b4b60..47376a1 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[7.1].define(version: 2024_08_11_143801) do +ActiveRecord::Schema[7.1].define(version: 2024_08_11_154115) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -44,6 +44,8 @@ ActiveRecord::Schema[7.1].define(version: 2024_08_11_143801) do t.string "phone" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.uuid "group_id", null: false + t.index ["group_id"], name: "index_guests_on_group_id" end create_table "seats", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| @@ -94,6 +96,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_08_11_143801) do end add_foreign_key "groups", "groups", column: "parent_id" + add_foreign_key "guests", "groups" add_foreign_key "seats", "guests" add_foreign_key "seats", "tables_arrangements", on_delete: :cascade add_foreign_key "taggings", "tags" diff --git a/db/seeds.rb b/db/seeds.rb index 5103a7d..53c3376 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -22,82 +22,44 @@ Expense.create!(name: 'Transportation', amount: 3000, pricing_type: 'fixed') Expense.create!(name: 'Invitations', amount: 200, pricing_type: 'fixed') Expense.create!(name: 'Cake', amount: 500, pricing_type: 'fixed') -Group.create!(name: "Jim's guests", icon: "pi pi-heart").tap do |parent| - parent.children.create!(name: "Jim's family", icon: "pi pi-users").tap do |family| - family.children.create!(name: "Jim's close family", icon: "pi pi-home") - family.children.create!(name: "Jim's cousins", icon: "pi pi-home") - family.children.create!(name: "Jim's relatives", icon: "pi pi-home") +Group.create!(name: "Jim's guests", icon: 'pi pi-heart').tap do |parent| + parent.children.create!(name: "Jim's family", icon: 'pi pi-users').tap do |family| + family.children.create!(name: "Jim's close family", icon: 'pi pi-home') + family.children.create!(name: "Jim's cousins", icon: 'pi pi-home') + family.children.create!(name: "Jim's relatives", icon: 'pi pi-home') end - parent.children.create!(name: "Jim's friends", icon: "pi pi-bullseye") - parent.children.create!(name: "Jim's work", icon: "pi pi-desktop").tap do |work| - work.children.create!(name: "Jim's besties at work", icon: "pi pi-briefcase") - end -end - -Group.create!(name: "Pam's guests", icon: "pi pi-heart-fill").tap do |parent| - parent.children.create!(name: "Pam's family", icon: "pi pi-users").tap do |family| - family.children.create!(name: "Pam's close family", icon: "pi pi-home") - family.children.create!(name: "Pam's cousins", icon: "pi pi-home") - family.children.create!(name: "Pam's relatives", icon: "pi pi-home") + parent.children.create!(name: "Jim's friends", icon: 'pi pi-bullseye') + parent.children.create!(name: "Jim's work", icon: 'pi pi-desktop').tap do |work| + work.children.create!(name: "Jim's besties at work", icon: 'pi pi-briefcase') end - parent.children.create!(name: "Pam's friends", icon: "pi pi-bullseye") - parent.children.create!(name: "Pam's work", icon: "pi pi-desktop").tap do |work| - work.children.create!(name: "Pam's besties at work", icon: "pi pi-briefcase") - end end -Group.create!(name: "Common guests", icon: "pi pi-users").tap do |parent| - parent.children.create!(name: "College friends", icon: "pi pi-calculator") - parent.children.create!(name: "High school friends", icon: "pi pi-crown") - parent.children.create!(name: "Childhood friends", icon: "pi pi-envelope") +Group.create!(name: "Pam's guests", icon: 'pi pi-heart-fill').tap do |parent| + parent.children.create!(name: "Pam's family", icon: 'pi pi-users').tap do |family| + family.children.create!(name: "Pam's close family", icon: 'pi pi-home') + family.children.create!(name: "Pam's cousins", icon: 'pi pi-home') + family.children.create!(name: "Pam's relatives", icon: 'pi pi-home') + end + parent.children.create!(name: "Pam's friends", icon: 'pi pi-bullseye') + parent.children.create!(name: "Pam's work", icon: 'pi pi-desktop').tap do |work| + work.children.create!(name: "Pam's besties at work", icon: 'pi pi-briefcase') + end end -samples = { - close_family_a: 10, - close_family_b: 10, - cousins_a: 20, - cousins_b: 15, - relatives_a: 15, - relatives_b: 10, - work_a: 10, - work_b: 10, - besties_work_a: 5, - besties_work_b: 5, - college_friends_a: 10, - college_friends_b: 10, - high_school_friends_a: 10, - high_school_friends_b: 10, - childhood_friends_a: 10, - childhood_friends_b: 10, - basket_team_a: 10, - football_team_a: 15, - dance_club: 10 -}.each_with_object([]) do |(affinity_group, count), acc| - count.times { acc << affinity_group } +Group.create!(name: 'Common guests', icon: 'pi pi-users').tap do |parent| + parent.children.create!(name: 'College friends', icon: 'pi pi-calculator') + parent.children.create!(name: 'High school friends', icon: 'pi pi-crown') + parent.children.create!(name: 'Childhood friends', icon: 'pi pi-envelope') end +groups = Group.all + NUMBER_OF_GUESTS.times do - guest = Guest.create!(first_name: Faker::Name.first_name, - last_name: Faker::Name.last_name, - email: Faker::Internet.email, - phone: Faker::PhoneNumber.cell_phone) - - guest.affinity_group_list.add(samples.sample) - guest.save! -end - -# Add unbreakable bonds -Guest.affinity_group_counts.each do |group| - couples = (group.taggings_count / 4).floor - - guests_involved = Guest.tagged_with(group.name).limit(couples * 2) - guests_involved.each_slice(2) do |a, b| - bond_name = "#{a.full_name} & #{b.full_name}" - - a.unbreakable_bond_list.add(bond_name) - b.unbreakable_bond_list.add(bond_name) - - a.save! - b.save! - end + Guest.create!( + first_name: Faker::Name.first_name, + last_name: Faker::Name.last_name, + email: Faker::Internet.email, + phone: Faker::PhoneNumber.cell_phone, + group: groups.sample + ) end From de93ffb643570f997e16f9868b85576bfe9e75bb Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Sun, 11 Aug 2024 18:56:38 +0200 Subject: [PATCH 10/16] Return number of guests per group --- app/controllers/groups_controller.rb | 3 ++- app/serializers/serializable_group.rb | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 461a67f..0f489fb 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -1,5 +1,6 @@ class GroupsController < ApplicationController def index - render jsonapi: Group.where(parent_id: nil), include: [children: [children: [:children]]] + roots = Group.where(parent_id: nil) + render jsonapi: roots, include: [children: [children: [:children]]] end end diff --git a/app/serializers/serializable_group.rb b/app/serializers/serializable_group.rb index e90dc52..f832475 100644 --- a/app/serializers/serializable_group.rb +++ b/app/serializers/serializable_group.rb @@ -4,4 +4,8 @@ class SerializableGroup < JSONAPI::Serializable::Resource attributes :name, :icon has_many :children + + attribute :guest_count do + @object.guests.count + end end From c177131672a14ef1852c24dad560c343f765e4e5 Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Sun, 11 Aug 2024 18:59:27 +0200 Subject: [PATCH 11/16] Fix factories --- spec/factories/groups.rb | 3 +-- spec/factories/guest.rb | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/spec/factories/groups.rb b/spec/factories/groups.rb index a8fe677..9bfade0 100644 --- a/spec/factories/groups.rb +++ b/spec/factories/groups.rb @@ -1,7 +1,6 @@ FactoryBot.define do factory :group do - name { "MyString" } - icon { "MyString" } + sequence(:name) { |i| "Group #{i}" } order { 1 } end end diff --git a/spec/factories/guest.rb b/spec/factories/guest.rb index f761dd9..7ff9066 100644 --- a/spec/factories/guest.rb +++ b/spec/factories/guest.rb @@ -1,5 +1,7 @@ FactoryBot.define do factory :guest do + association :group + first_name { Faker::Name.first_name } last_name { Faker::Name.last_name } email { Faker::Internet.email } From cb42b86136d7987e96f89ed6250cc9540d14c77d Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Sun, 11 Aug 2024 19:24:24 +0200 Subject: [PATCH 12/16] Include confirmation status --- app/models/guest.rb | 8 ++++++++ app/serializers/serializable_guest.rb | 6 +++++- db/migrate/20240811170021_add_status_to_guest.rb | 5 +++++ db/schema.rb | 3 ++- db/seeds.rb | 3 ++- 5 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20240811170021_add_status_to_guest.rb diff --git a/app/models/guest.rb b/app/models/guest.rb index 927a589..cc4f615 100644 --- a/app/models/guest.rb +++ b/app/models/guest.rb @@ -1,6 +1,14 @@ class Guest < ApplicationRecord acts_as_taggable_on :affinity_groups, :unbreakable_bonds belongs_to :group + + enum status: { + considered: 0, + invited: 10, + confirmed: 20, + declined: 30 + } + def full_name "#{first_name} #{last_name}" end diff --git a/app/serializers/serializable_guest.rb b/app/serializers/serializable_guest.rb index 3311d8b..647c106 100644 --- a/app/serializers/serializable_guest.rb +++ b/app/serializers/serializable_guest.rb @@ -1,7 +1,7 @@ class SerializableGuest < JSONAPI::Serializable::Resource type 'guest' - attributes :id, :email, :group_id + attributes :id, :email, :group_id, :status attribute :name do "#{@object.first_name} #{@object.last_name}" @@ -10,4 +10,8 @@ class SerializableGuest < JSONAPI::Serializable::Resource attribute :group_name do @object.group.name end + + attribute :status do + @object.status.capitalize + end end diff --git a/db/migrate/20240811170021_add_status_to_guest.rb b/db/migrate/20240811170021_add_status_to_guest.rb new file mode 100644 index 0000000..cd7be5b --- /dev/null +++ b/db/migrate/20240811170021_add_status_to_guest.rb @@ -0,0 +1,5 @@ +class AddStatusToGuest < ActiveRecord::Migration[7.1] + def change + add_column :guests, :status, :integer, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index 47376a1..c4145db 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[7.1].define(version: 2024_08_11_154115) do +ActiveRecord::Schema[7.1].define(version: 2024_08_11_170021) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -45,6 +45,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_08_11_154115) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.uuid "group_id", null: false + t.integer "status", default: 0 t.index ["group_id"], name: "index_guests_on_group_id" end diff --git a/db/seeds.rb b/db/seeds.rb index 53c3376..391d6e1 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -60,6 +60,7 @@ NUMBER_OF_GUESTS.times do last_name: Faker::Name.last_name, email: Faker::Internet.email, phone: Faker::PhoneNumber.cell_phone, - group: groups.sample + group: groups.sample, + status: Guest.statuses.keys.sample ) end From 6b3bea998501bcf0de94aa0265a29769dda42b4f Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Sun, 11 Aug 2024 22:57:03 +0200 Subject: [PATCH 13/16] Add CI step to build docker image --- .github/workflows/build.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..f7a5815 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,31 @@ +name: Build docker image +on: + push: + branches: + - main + pull_request: +jobs: + build-static-assets: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: bustikiller/wedding-planner:latest + cache-from: type=registry,ref=user/app:latest + cache-to: type=inline \ No newline at end of file From 44274fddca81b35e0cdc58057d8989a2dd5fd6c9 Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Sun, 11 Aug 2024 23:08:10 +0200 Subject: [PATCH 14/16] Install nodejs to povide a javascript runtime environment --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index a885e56..80ee039 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # syntax = docker/dockerfile:1 # Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile -ARG RUBY_VERSION=3.2.0 +ARG RUBY_VERSION=3.3.4 FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base # Rails app lives here @@ -13,6 +13,7 @@ ENV RAILS_ENV="production" \ BUNDLE_PATH="/usr/local/bundle" \ BUNDLE_WITHOUT="development" +RUN apt-get update && apt-get install -y nodejs # Throw-away build stage to reduce size of final image FROM base as build From 7e16000833f66399b360cc997e72d943d0ec8d8d Mon Sep 17 00:00:00 2001 From: Manuel Bustillo Date: Sun, 11 Aug 2024 23:09:07 +0200 Subject: [PATCH 15/16] Install CSV as a gem instead of from stdlib --- Gemfile | 1 + Gemfile.lock | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Gemfile b/Gemfile index bea2d7b..6f53d2e 100644 --- a/Gemfile +++ b/Gemfile @@ -3,6 +3,7 @@ source 'https://rubygems.org' ruby '3.3.4' gem 'acts-as-taggable-on' gem 'bootsnap', require: false +gem 'csv' gem 'importmap-rails' gem 'jbuilder' gem 'money' diff --git a/Gemfile.lock b/Gemfile.lock index 0e23ca2..b74ca5f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -92,6 +92,7 @@ GEM concurrent-ruby (1.3.4) connection_pool (2.4.1) crass (1.0.6) + csv (3.2.8) date (3.3.4) debug (1.9.2) irb (~> 1.10) @@ -318,6 +319,7 @@ PLATFORMS DEPENDENCIES acts-as-taggable-on bootsnap + csv debug factory_bot_rails faker From 01d22f32d2469b93eda90b64c186b9fb44e83ca9 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sun, 11 Aug 2024 23:16:01 +0000 Subject: [PATCH 16/16] Update dependency csv to v3.3.0 --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index b74ca5f..8b9b054 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -92,7 +92,7 @@ GEM concurrent-ruby (1.3.4) connection_pool (2.4.1) crass (1.0.6) - csv (3.2.8) + csv (3.3.0) date (3.3.4) debug (1.9.2) irb (~> 1.10)