Add CRUD for game systems

This commit is contained in:
Trevor Vallender 2024-05-26 11:42:48 +01:00
parent 716176a1b8
commit 93359a5b59
16 changed files with 219 additions and 2 deletions

View File

@ -0,0 +1,57 @@
class Admin::GameSystemsController < AdminController
before_action :set_game_system, only: [ :show, :edit, :update, :destroy ]
def index
@game_systems = GameSystem.all
end
def show
end
def new
@game_system = GameSystem.new
end
def create
@game_system = GameSystem.new(game_system_params)
if @game_system.save
redirect_to admin_game_system_path(@game_system), notice: t(".success", name: @game_system.name)
else
flash.now[:alert] = t(".error", name: @game_system.name)
render :new, status: :unprocessable_entity
end
end
def edit
end
def update
if @game_system.update(game_system_params)
redirect_to admin_game_system_path(@game_system), notice: t(".success", name: @game_system.name)
else
flash.now[:alert] = t(".error", name: @game_system.name)
render :edit, status: :unprocessable_entity
end
end
def destroy
name = @game_system.name
if @game_system.destroy
redirect_to admin_game_systems_path, notice: t(".success", name:)
else
flash[:alert] = t(".error", name:)
redirect_to admin_game_systems_path, alert: t(".error")
end
end
private
def game_system_params
params.require(:game_system).permit(
:name,
)
end
def set_game_system
@game_system = GameSystem.find(params[:id])
end
end

View File

@ -1,3 +1,5 @@
class GameSystem < ApplicationRecord class GameSystem < ApplicationRecord
validates :name, presence: true validates :name, presence: true,
uniqueness: true,
length: { maximum: 100 }
end end

View File

@ -0,0 +1,8 @@
<% # locals: (game_system: @game_system, button_text:, url:) %>
<%= form_with model: @game_system, url: do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.submit button_text %>
<% end %>

View File

@ -0,0 +1,4 @@
<h2><%= t(".edit", name: @game_system.name) %></h2>
<%= render partial: "form",
locals: { button_text: t(".update", name: @game_system.name), url: admin_game_system_path(@game_system) } %>

View File

@ -0,0 +1,9 @@
<% content_for :title, t(".game_systems") %>
<%= link_to t(".new_game_system"), new_admin_game_system_path %>
<% @game_systems.each do |game_system| %>
<div id=<%= dom_id(game_system) %> class="game-system">
<%= link_to game_system.name, admin_game_system_path(game_system) %>
</div>
<% end %>

View File

@ -0,0 +1,3 @@
<h2><%= t(".new") %></h2>
<%= render partial: "form", locals: { button_text: t(".create"), url: admin_game_systems_path } %>

View File

@ -0,0 +1,6 @@
<h2><%= @game_system.name %></h2>
<%= link_to t("edit"), edit_admin_game_system_path(@game_system) %>
<%= link_to t("delete"), admin_game_system_path(@game_system),
data: { turbo_method: :delete, turbo_confirm: t(".confirm_delete", name: @game_system.name) } %>

View File

@ -1 +1,2 @@
<% content_for :title, t(".dashboard") %>
<%= t(".intro") %> <%= t(".intro") %>

View File

@ -2,6 +2,8 @@
<h2><%= t("administration") %>: <%= content_for :title %></h2> <h2><%= t("administration") %>: <%= content_for :title %></h2>
<nav> <nav>
<ul> <ul>
<li><%= link_to t(".dashboard"), admin_index_path %></li>
<li><%= link_to t(".game_systems"), admin_game_systems_path %></li>
</ul> </ul>
</nav> </nav>
<% end %> <% end %>

View File

@ -31,6 +31,7 @@
</header> </header>
<%= render partial: "shared/flash_messages" %> <%= render partial: "shared/flash_messages" %>
<main> <main>
<%= yield(:submenu) if content_for?(:submenu) %>
<%= yield %> <%= yield %>
</main> </main>
</body> </body>

View File

@ -5,7 +5,12 @@ en:
log_out: Log out log_out: Log out
sign_up: Sign up sign_up: Sign up
not_authenticated: You need to log in to access this page. not_authenticated: You need to log in to access this page.
edit: Edit
delete: Delete
layouts: layouts:
admin:
dashboard: Dashboard
game_systems: Game Systems
mailer: mailer:
greeting: "Hello, %{name}" greeting: "Hello, %{name}"
sign_off: | sign_off: |
@ -18,7 +23,30 @@ en:
error: "Invalid token, could not verify your account." error: "Invalid token, could not verify your account."
admin: admin:
index: index:
dashboard: Dashboard
intro: With great power comes great responsibility intro: With great power comes great responsibility
game_systems:
error: Error
index:
game_systems: Game systems
new_game_system: New game system
new:
new: New game system
create: Add game system
create:
success: “%{name}” has been created.
error: “%{name}” could not be created.
show:
confirm_delete: Are you sure you want to delete “%{name}”?
edit:
edit: Edit %{name}
update: Update %{name}
update:
success: Successfully updated “%{name}”.
error: “%{name}” could not be updated.
destroy:
success: Successfully deleted “%{name}”.
error: “%{name}” could not be deleted.
sessions: sessions:
create: create:
success: "Hello, %{name}!" success: "Hello, %{name}!"

View File

@ -13,6 +13,9 @@ Rails.application.routes.draw do
resources :tables, only: [ :index ] resources :tables, only: [ :index ]
resources :admin, only: [ :index ] resources :admin, only: [ :index ]
namespace :admin do
resources :game_systems
end
get "up" => "rails/health#show", as: :rails_health_check get "up" => "rails/health#show", as: :rails_health_check
end end

View File

@ -0,0 +1,7 @@
class AddUniqueIndexToGameSystemName < ActiveRecord::Migration[7.1]
def change
add_index :game_systems, :name, unique: true
add_check_constraint :game_systems, "length(name) <= 100", name: "chk_name_max_length"
end
end

4
db/schema.rb generated
View File

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.1].define(version: 2024_05_26_085315) do ActiveRecord::Schema[7.1].define(version: 2024_05_26_102908) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -18,6 +18,8 @@ ActiveRecord::Schema[7.1].define(version: 2024_05_26_085315) do
t.string "name", null: false t.string "name", null: false
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.index ["name"], name: "index_game_systems_on_name", unique: true
t.check_constraint "length(name::text) <= 100", name: "chk_name_max_length"
end end
create_table "site_roles", force: :cascade do |t| create_table "site_roles", force: :cascade do |t|

View File

@ -0,0 +1,20 @@
require "test_helper"
class AdminGameSystemsControllerTest < ActionDispatch::IntegrationTest
test "should get game systems index if signed in as admin" do
sign_in users(:admin)
get admin_game_systems_path
assert_response :success
end
test "should not get game systems index if signed in as non-admin user" do
sign_in users(:trevor)
get admin_game_systems_path
assert_response :forbidden
end
test "should not get game systems index if not signed in" do
get admin_game_systems_path
assert_redirected_to login_path
end
end

View File

@ -0,0 +1,64 @@
require "test_helper"
class AdminGameSystemsIntegrationTest < ActionDispatch::IntegrationTest
test "index should show most all game systems" do
sign_in users(:admin)
get admin_game_systems_path
assert_response :success
assert_select ".game-system", GameSystem.all.size
end
test "show should show game system" do
sign_in users(:admin)
get admin_game_system_path(game_systems(:troika))
assert_response :success
assert_select "h2", game_systems(:troika).name
end
test "new should show form to create new game system" do
sign_in users(:admin)
get new_admin_game_system_path
assert_response :success
assert_select "form[action=?][method=?]", admin_game_systems_path, "post"
end
test "create should create new game system" do
sign_in users(:admin)
assert_difference "GameSystem.count", 1 do
post admin_game_systems_path, params: { game_system: { name: "Test Game System" } }
end
assert_redirected_to admin_game_system_path(GameSystem.last)
end
test "create should fail if game system already exists" do
sign_in users(:admin)
assert_no_difference "GameSystem.count" do
post admin_game_systems_path, params: { game_system: { name: game_systems(:troika).name } }
end
assert_response :unprocessable_entity
end
test "edit should show form to edit game system" do
sign_in users(:admin)
get edit_admin_game_system_path(game_systems(:troika))
assert_response :success
assert_select "form[action=?][method=?]", admin_game_system_path(game_systems(:troika)), "post"
end
test "update should update game system" do
sign_in users(:admin)
patch admin_game_system_path(game_systems(:troika)), params: { game_system: { name: "Test Game System" } }
assert_redirected_to admin_game_system_path(game_systems(:troika))
end
test "destroy should destroy game system" do
sign_in users(:admin)
assert_difference "GameSystem.count", -1 do
delete admin_game_system_path(game_systems(:troika))
end
assert_redirected_to admin_game_systems_path
end
end