From 3ce908199640f4d8f972cce78745dcef4016d1f5 Mon Sep 17 00:00:00 2001 From: Trevor Vallender Date: Tue, 28 May 2024 20:16:43 +0100 Subject: [PATCH] CRUD actions for tables --- app/assets/stylesheets/layout.css | 1 + app/controllers/tables_controller.rb | 55 +++++++++++++++++ app/helpers/application_helper.rb | 4 ++ app/models/user.rb | 1 + app/views/tables/_form.html.erb | 11 ++++ app/views/tables/_table.html.erb | 5 ++ app/views/tables/edit.html.erb | 8 +++ app/views/tables/index.html.erb | 11 +++- app/views/tables/new.html.erb | 6 ++ app/views/tables/show.html.erb | 12 ++++ config/locales/en.yml | 25 ++++++++ config/routes.rb | 2 +- test/controllers/tables_controller_test.rb | 68 ++++++++++++++++++++++ 13 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 app/views/tables/_form.html.erb create mode 100644 app/views/tables/_table.html.erb create mode 100644 app/views/tables/edit.html.erb create mode 100644 app/views/tables/new.html.erb create mode 100644 app/views/tables/show.html.erb create mode 100644 test/controllers/tables_controller_test.rb diff --git a/app/assets/stylesheets/layout.css b/app/assets/stylesheets/layout.css index c54d3ad..d8a70a2 100644 --- a/app/assets/stylesheets/layout.css +++ b/app/assets/stylesheets/layout.css @@ -6,6 +6,7 @@ body { font-size: 1.1em; margin: 0 auto; max-width: 80em; + padding: 1em; } main { diff --git a/app/controllers/tables_controller.rb b/app/controllers/tables_controller.rb index a782914..2672e95 100644 --- a/app/controllers/tables_controller.rb +++ b/app/controllers/tables_controller.rb @@ -1,6 +1,61 @@ # frozen_string_literal: true class TablesController < ApplicationController + before_action :set_table, only: [ :show, :edit, :update, :destroy ] + def index + @tables = Current.user.tables end + + def show + end + + def new + @table = Table.new + end + + def create + @table = Current.user.tables.new(table_params) + @table.slug = helpers.generate_slug_for(model: Table, string: @table.name) + if @table.save + redirect_to @table, notice: t(".success", name: @table.name) + else + flash.now[:alert] = t(".error") + render :new, status: :unprocessable_entity + end + end + + def edit + end + + def update + if @table.update(table_params) + redirect_to @table, notice: t(".success", name: @table.name) + else + flash.now[:alert] = t(".error") + render :edit, status: :unprocessable_entity + end + end + + def destroy + if @table.destroy + redirect_to tables_path, notice: t(".success", name: @table.name) + else + flash[:alert] = t(".error", name: @table.name) + redirect_to tables_path + end + end + + private + + def set_table + @table = Current.user.tables.find(params[:id]) + end + + def table_params + params.require(:table).permit( + :name, + :game_system_id, + ) + end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 15b06f0..d2a7d74 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,4 +1,8 @@ # frozen_string_literal: true module ApplicationHelper + def generate_slug_for(model:, string:) + # TODO: Need to ensure this is unique for that model + string.parameterize + end end diff --git a/app/models/user.rb b/app/models/user.rb index 34a68f1..619ea81 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -2,6 +2,7 @@ class User < ApplicationRecord has_and_belongs_to_many :site_roles + has_many :tables, foreign_key: :owner_id has_secure_password generates_token_for :password_reset, expires_in: 4.hours do diff --git a/app/views/tables/_form.html.erb b/app/views/tables/_form.html.erb new file mode 100644 index 0000000..d819d90 --- /dev/null +++ b/app/views/tables/_form.html.erb @@ -0,0 +1,11 @@ +<%# locals: (table:, button_text:) -%> + +<%= form_with model: @table do |f| %> + <%= f.label :name %> + <%= f.text_field :name %> + + <%= f.label :game_system_id %> + <%= f.collection_select :game_system_id, GameSystem.all, :id, :name %> + + <%= f.submit button_text %> +<% end %> diff --git a/app/views/tables/_table.html.erb b/app/views/tables/_table.html.erb new file mode 100644 index 0000000..79499a4 --- /dev/null +++ b/app/views/tables/_table.html.erb @@ -0,0 +1,5 @@ +<%# locals: (table:) -%> + +
+

<%= link_to table.name, table %>

+
diff --git a/app/views/tables/edit.html.erb b/app/views/tables/edit.html.erb new file mode 100644 index 0000000..d8b15c0 --- /dev/null +++ b/app/views/tables/edit.html.erb @@ -0,0 +1,8 @@ +<% content_for :title, t(".edit_table", name: @table.name) %> + +

<%= t(".edit_table", name: @table.name) %>

+ +<%= link_to t(".delete_table", name: @table.name), table_path(@table), + data: { turbo_method: :delete, turbo_confirm: t(".delete_table_confirmation", name: @table.name) } %> +<%= render partial: "tables/form", + locals: { table: @table, button_text: t(".update_table") } %> diff --git a/app/views/tables/index.html.erb b/app/views/tables/index.html.erb index d87d760..c90911c 100644 --- a/app/views/tables/index.html.erb +++ b/app/views/tables/index.html.erb @@ -1 +1,10 @@ -

Hello

+<% content_for :title, t(".tables") %> + +<%= link_to t(".new_table"), new_table_path %> + +

Your tables

+<% if @tables.any? %> + <%= render @tables %> +<% else %> +

You have no tables.

+<% end %> diff --git a/app/views/tables/new.html.erb b/app/views/tables/new.html.erb new file mode 100644 index 0000000..6a1480f --- /dev/null +++ b/app/views/tables/new.html.erb @@ -0,0 +1,6 @@ +<% content_for :title, t(".new_table") %> + +

<%= t(".new_table") %>

+ +<%= render partial: "tables/form", + locals: { table: @table, button_text: t(".create_table") } %> diff --git a/app/views/tables/show.html.erb b/app/views/tables/show.html.erb new file mode 100644 index 0000000..b748b1d --- /dev/null +++ b/app/views/tables/show.html.erb @@ -0,0 +1,12 @@ +<% content_for :title, @table.name %> + +

<%= @table.name %>

+ +<%= link_to t(".edit_table"), edit_table_path(@table) %> + +
+
<%= t(".game_system") %>:
+
<%= @table.game_system.name %>
+
<%= t(".owner") %>:
+
<%= @table.owner.username %>
+
diff --git a/config/locales/en.yml b/config/locales/en.yml index e423344..963e275 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -56,6 +56,31 @@ en: destroy: log_out: Log out success: "You have signed out." + tables: + index: + new_table: Create a table + tables: Tables + show: + edit_table: Edit table + game_system: Game system + owner: Owner + new: + new_table: New table + create_table: Create table + create: + success: Your table “%{name}” has been created. + error: Failed to create table + edit: + delete_table: Delete %{name} + delete_table_confirmation: Are you sure you want to delete %{name}? + edit_table: Edit %{name} + update_table: Update table + update: + success: Updated table “%{name}”. + error: Failed to update table. + destroy: + success: Deleted table “%{name}”. + error: Failed to delete table. users: validations: email_format: "must be a valid email address" diff --git a/config/routes.rb b/config/routes.rb index bae428b..5d47767 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -12,7 +12,7 @@ Rails.application.routes.draw do resources :account_verifications, only: [ :show ] resources :sessions, only: [ :new, :create, :destroy ] - resources :tables, only: [ :index ] + resources :tables resources :admin, only: [ :index ] namespace :admin do diff --git a/test/controllers/tables_controller_test.rb b/test/controllers/tables_controller_test.rb new file mode 100644 index 0000000..e891e9d --- /dev/null +++ b/test/controllers/tables_controller_test.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +require "test_helper" + +class TablesControllerTest < ActionDispatch::IntegrationTest + test "should get index" do + sign_in users(:trevor) + get tables_url + assert_response :success + end + + test "should get show" do + sign_in users(:trevor) + get table_url(tables(:table)) + assert_response :success + end + + test "should get new" do + sign_in users(:trevor) + get new_table_url + assert_response :success + end + + test "should create table" do + sign_in users(:trevor) + assert_changes("Table.count", +1) do + post(tables_url, params: { table: table_params }) + end + assert_redirected_to table_path(Table.last) + end + + test "should alert to invalid table" do + sign_in users(:trevor) + assert_no_changes("Table.count") do + post(tables_url, params: { table: { name: "new_table" } }) + end + assert_response :unprocessable_entity + end + + test "should get edit" do + sign_in users(:trevor) + get edit_table_url(tables(:table)) + assert_response :success + end + + test "should update table" do + sign_in users(:trevor) + patch table_url(tables(:table)), params: { table: { name: "new name" } } + assert_redirected_to table_path(tables(:table)) + end + + test "should destroy table" do + sign_in users(:trevor) + assert_difference("Table.count", -1) do + delete table_url(tables(:table)) + end + assert_redirected_to tables_url + end + + private + + def table_params + { + name: "A new table", + game_system_id: game_systems(:dnd).id, + } + end +end