From 44507bb85c16664f848144fc24989d6a58e1edf7 Mon Sep 17 00:00:00 2001 From: sto Date: Thu, 20 Mar 2025 09:19:39 +0100 Subject: [PATCH] Add contestants --- app/controllers/contestants_controller.rb | 51 +++++++++++++++++++ app/controllers/contests_controller.rb | 1 + app/controllers/puzzles_controller.rb | 9 +--- app/helpers/contestants_helper.rb | 2 + app/models/contest.rb | 1 + app/models/contestant.rb | 4 ++ app/views/contestants/_form.html.slim | 17 +++++++ app/views/contestants/edit.html.slim | 1 + app/views/contestants/new.html.slim | 1 + app/views/contests/show.html.slim | 19 ++++++- app/views/puzzles/index.html.slim | 8 --- app/views/puzzles/show.html.slim | 7 --- config/routes.rb | 1 + .../20250320080142_create_contestants.rb | 11 ++++ db/schema.rb | 12 ++++- .../contestants_controller_test.rb | 7 +++ test/fixtures/contestants.yml | 11 ++++ test/models/contestant_test.rb | 7 +++ 18 files changed, 145 insertions(+), 25 deletions(-) create mode 100644 app/controllers/contestants_controller.rb create mode 100644 app/helpers/contestants_helper.rb create mode 100644 app/models/contestant.rb create mode 100644 app/views/contestants/_form.html.slim create mode 100644 app/views/contestants/edit.html.slim create mode 100644 app/views/contestants/new.html.slim delete mode 100644 app/views/puzzles/index.html.slim delete mode 100644 app/views/puzzles/show.html.slim create mode 100644 db/migrate/20250320080142_create_contestants.rb create mode 100644 test/controllers/contestants_controller_test.rb create mode 100644 test/fixtures/contestants.yml create mode 100644 test/models/contestant_test.rb diff --git a/app/controllers/contestants_controller.rb b/app/controllers/contestants_controller.rb new file mode 100644 index 0000000..ed2a031 --- /dev/null +++ b/app/controllers/contestants_controller.rb @@ -0,0 +1,51 @@ +class ContestantsController < ApplicationController + before_action :set_contest + before_action :set_contestant, only: %i[ destroy edit update] + + def edit + @title = "Edit contestant" + end + + def new + @contestant = Contestant.new + @title = "New contestant" + end + + def create + @contestant = Contestant.new(contestant_params) + @contestant.contest_id = @contest.id + if @contestant.save + redirect_to contest_path(@contest) + else + @title = "New contestant" + render :new, status: :unprocessable_entity + end + end + + def update + if @contestant.update(contestant_params) + redirect_to @contest + else + render :edit, status: :unprocessable_entity + end + end + + def destroy + @contestant.destroy + redirect_to contest_path(@contest) + end + + private + + def set_contest + @contest = Contest.find(params[:contest_id]) + end + + def set_contestant + @contestant = Contestant.find(params[:id]) + end + + def contestant_params + params.expect(contestant: [ :email, :name ]) + end +end diff --git a/app/controllers/contests_controller.rb b/app/controllers/contests_controller.rb index 5b289eb..725d50c 100644 --- a/app/controllers/contests_controller.rb +++ b/app/controllers/contests_controller.rb @@ -8,6 +8,7 @@ class ContestsController < ApplicationController def show @title = @contest.name + @contestants = @contest.contestants @puzzles = @contest.puzzles set_badges end diff --git a/app/controllers/puzzles_controller.rb b/app/controllers/puzzles_controller.rb index f559c20..84f5814 100644 --- a/app/controllers/puzzles_controller.rb +++ b/app/controllers/puzzles_controller.rb @@ -1,13 +1,6 @@ class PuzzlesController < ApplicationController before_action :set_contest - before_action :set_puzzle, only: %i[ edit destroy show update] - - def index - @puzzles = Puzzle.all - end - - def show - end + before_action :set_puzzle, only: %i[ destroy edit update] def edit @title = "Edit contest puzzle" diff --git a/app/helpers/contestants_helper.rb b/app/helpers/contestants_helper.rb new file mode 100644 index 0000000..38881f2 --- /dev/null +++ b/app/helpers/contestants_helper.rb @@ -0,0 +1,2 @@ +module ContestantsHelper +end diff --git a/app/models/contest.rb b/app/models/contest.rb index cf9f558..4e39667 100644 --- a/app/models/contest.rb +++ b/app/models/contest.rb @@ -1,4 +1,5 @@ class Contest < ApplicationRecord belongs_to :user + has_many :contestants, dependent: :destroy has_many :puzzles, dependent: :destroy end diff --git a/app/models/contestant.rb b/app/models/contestant.rb new file mode 100644 index 0000000..9ba5d0b --- /dev/null +++ b/app/models/contestant.rb @@ -0,0 +1,4 @@ +class Contestant < ApplicationRecord + belongs_to :contest + validates :name, presence: true +end diff --git a/app/views/contestants/_form.html.slim b/app/views/contestants/_form.html.slim new file mode 100644 index 0000000..149547a --- /dev/null +++ b/app/views/contestants/_form.html.slim @@ -0,0 +1,17 @@ += form_with model: contestant, url: url, method: method do |form| + .row.mb-3 + .col + .form-floating + = form.text_field :name, autocomplete: "off", class: "form-control" + = form.label :name, class: "required" + .row.mb-3 + .col + .form-floating + = form.text_field :email, autocomplete: "off", class: "form-control" + = form.label :email + .form-text Optional. Fill this only if you intend to send emails through this app. + .row.mt-4 + .col + - if method == :patch + = link_to "Delete", contest_contestant_path(contest, contestant), data: { turbo_method: :delete }, class: "btn btn-danger me-2" + = form.submit submit_text, class: "btn btn-primary" \ No newline at end of file diff --git a/app/views/contestants/edit.html.slim b/app/views/contestants/edit.html.slim new file mode 100644 index 0000000..fd4680d --- /dev/null +++ b/app/views/contestants/edit.html.slim @@ -0,0 +1 @@ += render "form", contest: @contest, contestant: @contestant, submit_text: "Save", method: :patch, url: "/contests/#{@contest.id}/contestants/#{@contestant.id}" \ No newline at end of file diff --git a/app/views/contestants/new.html.slim b/app/views/contestants/new.html.slim new file mode 100644 index 0000000..a9410a2 --- /dev/null +++ b/app/views/contestants/new.html.slim @@ -0,0 +1 @@ += render "form", contest: @contest, contestant: @contestant, submit_text: "Add", method: :post, url: "/contests/#{@contest.id}/contestants" \ No newline at end of file diff --git a/app/views/contests/show.html.slim b/app/views/contests/show.html.slim index 744a68f..2dcff45 100644 --- a/app/views/contests/show.html.slim +++ b/app/views/contests/show.html.slim @@ -34,4 +34,21 @@ a.btn.btn-primary href=new_contest_puzzle_path(@contest) | Add puzzle .col-sm-6 - h4 Teams \ No newline at end of file + .row + .col + h4 + | Contestants + .row.row-cols-1.row-cols-md-3.g-4.mb-4 + - @contestants.each do |contestant| + .col + css: + .card:hover { background-color: lightblue; } + .card.h-100 + .card-header + = contestant.name + .card-body + a.stretched-link href=edit_contest_contestant_path(@contest, contestant) + .row + .col + a.btn.btn-primary href=new_contest_contestant_path(@contest) + | Add contestant diff --git a/app/views/puzzles/index.html.slim b/app/views/puzzles/index.html.slim deleted file mode 100644 index bc3dcfb..0000000 --- a/app/views/puzzles/index.html.slim +++ /dev/null @@ -1,8 +0,0 @@ -h1 Puzzles - -= link_to "New puzzle", new_puzzle_path - -div - - @puzzles.each do |puzzle| - div - = link_to puzzle.name, puzzle diff --git a/app/views/puzzles/show.html.slim b/app/views/puzzles/show.html.slim deleted file mode 100644 index 39ab81e..0000000 --- a/app/views/puzzles/show.html.slim +++ /dev/null @@ -1,7 +0,0 @@ -h1 = @puzzle.name - -= link_to "Back", puzzles_path - -= image_tag @puzzle.image if @puzzle.image.attached? - -= button_to "Delete", @puzzle, method: :delete, data: { turbo_confirm: "Are you suuure??" } \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 397cf87..b7fd097 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -9,6 +9,7 @@ Rails.application.routes.draw do root "contests#index" resources :contests do + resources :contestants resources :puzzles end resources :passwords, param: :token diff --git a/db/migrate/20250320080142_create_contestants.rb b/db/migrate/20250320080142_create_contestants.rb new file mode 100644 index 0000000..427b0db --- /dev/null +++ b/db/migrate/20250320080142_create_contestants.rb @@ -0,0 +1,11 @@ +class CreateContestants < ActiveRecord::Migration[8.0] + def change + create_table :contestants do |t| + t.string :name + t.string :email + t.belongs_to :contest, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 3d047b2..3c76d3b 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: 2025_03_20_075601) do +ActiveRecord::Schema[8.0].define(version: 2025_03_20_080142) do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false t.string "record_type", null: false @@ -39,6 +39,15 @@ ActiveRecord::Schema[8.0].define(version: 2025_03_20_075601) do t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true end + create_table "contestants", force: :cascade do |t| + t.string "name" + t.string "email" + t.integer "contest_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["contest_id"], name: "index_contestants_on_contest_id" + end + create_table "contests", force: :cascade do |t| t.string "name" t.integer "user_id", null: false @@ -78,6 +87,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_03_20_075601) do add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" + add_foreign_key "contestants", "contests" add_foreign_key "contests", "users" add_foreign_key "puzzles", "contests" add_foreign_key "sessions", "users" diff --git a/test/controllers/contestants_controller_test.rb b/test/controllers/contestants_controller_test.rb new file mode 100644 index 0000000..c1418d3 --- /dev/null +++ b/test/controllers/contestants_controller_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class ContestantsControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/test/fixtures/contestants.yml b/test/fixtures/contestants.yml new file mode 100644 index 0000000..ebb0c2a --- /dev/null +++ b/test/fixtures/contestants.yml @@ -0,0 +1,11 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + email: MyString + contest: one + +two: + name: MyString + email: MyString + contest: two diff --git a/test/models/contestant_test.rb b/test/models/contestant_test.rb new file mode 100644 index 0000000..dc92d79 --- /dev/null +++ b/test/models/contestant_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class ContestantTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end