From 1b2de86007508ba86c6c9cb99fbdcac178045131 Mon Sep 17 00:00:00 2001 From: David Gay Date: Sun, 2 May 2021 22:38:32 -0400 Subject: Character items and inventory, with ability to add and remove items --- app/controllers/characters/items_controller.rb | 5 +++ app/errors/item_quantity_error.rb | 2 ++ app/models/character.rb | 10 ++++++ app/models/character_item.rb | 25 +++++++++++++++ app/views/application/_navbar.html.erb | 11 +++---- app/views/characters/items/index.html.erb | 36 ++++++++++++++++++++++ config/routes.rb | 6 +++- .../20210503005919_create_character_items.rb | 11 +++++++ db/schema.rb | 14 ++++++++- test/fixtures/character_items.yml | 11 +++++++ test/models/character_item_test.rb | 7 +++++ 11 files changed, 129 insertions(+), 9 deletions(-) create mode 100644 app/controllers/characters/items_controller.rb create mode 100644 app/errors/item_quantity_error.rb create mode 100644 app/models/character_item.rb create mode 100644 app/views/characters/items/index.html.erb create mode 100644 db/migrate/20210503005919_create_character_items.rb create mode 100644 test/fixtures/character_items.yml create mode 100644 test/models/character_item_test.rb diff --git a/app/controllers/characters/items_controller.rb b/app/controllers/characters/items_controller.rb new file mode 100644 index 0000000..e1a30f8 --- /dev/null +++ b/app/controllers/characters/items_controller.rb @@ -0,0 +1,5 @@ +class Characters::ItemsController < ApplicationController + def index + @character_items = Character.find(params[:character_id]).character_items + end +end diff --git a/app/errors/item_quantity_error.rb b/app/errors/item_quantity_error.rb new file mode 100644 index 0000000..29576ca --- /dev/null +++ b/app/errors/item_quantity_error.rb @@ -0,0 +1,2 @@ +class ItemQuantityError < StandardError +end diff --git a/app/models/character.rb b/app/models/character.rb index 1c022ea..a158d88 100644 --- a/app/models/character.rb +++ b/app/models/character.rb @@ -1,5 +1,15 @@ class Character < ApplicationRecord belongs_to :user belongs_to :activity, optional: true + has_many :character_items + has_many :items, through: :character_items validates :name, presence: true + + def shift_item(gid, amount) + CharacterItem.transaction do + item = self.character_items.find_or_initialize_by(item: Item.find_by_gid(gid)) + item.increment(:quantity, amount) + item.save + end + end end diff --git a/app/models/character_item.rb b/app/models/character_item.rb new file mode 100644 index 0000000..b54f799 --- /dev/null +++ b/app/models/character_item.rb @@ -0,0 +1,25 @@ +class CharacterItem < ApplicationRecord + belongs_to :character + belongs_to :item + validates :quantity, presence: true + + after_initialize do + if self.new_record? + self.quantity ||= 0 + end + end + + after_save :destroy_if_zero_quantity + + scope :ordered_by_item_name, -> { includes(:item).order("items.name") } + + private + def destroy_if_zero_quantity + if self.quantity == 0 + destroy + elsif self.quantity < 0 + # TODO: Can improve this (at the least, with reporting, later). + raise ItemQuantityError + end + end +end diff --git a/app/views/application/_navbar.html.erb b/app/views/application/_navbar.html.erb index 5d3a2cb..85f4642 100644 --- a/app/views/application/_navbar.html.erb +++ b/app/views/application/_navbar.html.erb @@ -1,16 +1,13 @@ diff --git a/app/views/characters/items/index.html.erb b/app/views/characters/items/index.html.erb new file mode 100644 index 0000000..e313f7e --- /dev/null +++ b/app/views/characters/items/index.html.erb @@ -0,0 +1,36 @@ +

Inventory

+ + + + + + + + + + + + + <% @character_items.ordered_by_item_name.each do |ci| %> + + + + + + + + <% end %> + +
AmountItemEquipUseDestroy
<%= ci.quantity %><%= ci.item.name %> + <% if ci.item.equip_slot %> + <%= link_to "[Equip]", "#" %> + <% end %> + + <% if ci.item.usable? %> + <%= link_to "[Use]", "#" %> + <% end %> + + <%= link_to "[Destroy]", "#" %> + <%= link_to "[Destroy All]", "#" %> +
+ diff --git a/config/routes.rb b/config/routes.rb index e048a85..bd5793e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,5 +11,9 @@ Rails.application.routes.draw do put "users", to: "devise/registrations#update", as: "user_registration" end - resources :characters, only: [:show, :new, :create] + resources :characters, only: [:show, :new, :create] do + scope module: :characters do + resources :items, only: [:index] + end + end end diff --git a/db/migrate/20210503005919_create_character_items.rb b/db/migrate/20210503005919_create_character_items.rb new file mode 100644 index 0000000..50e926a --- /dev/null +++ b/db/migrate/20210503005919_create_character_items.rb @@ -0,0 +1,11 @@ +class CreateCharacterItems < ActiveRecord::Migration[6.1] + def change + create_table :character_items do |t| + t.references :character, null: false, foreign_key: true + t.references :item, null: false, foreign_key: true + t.integer :quantity + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 9072ac3..a86c111 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.define(version: 2021_05_03_002720) do +ActiveRecord::Schema.define(version: 2021_05_03_005919) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -24,6 +24,16 @@ ActiveRecord::Schema.define(version: 2021_05_03_002720) do t.datetime "updated_at", precision: 6, null: false end + create_table "character_items", force: :cascade do |t| + t.bigint "character_id", null: false + t.bigint "item_id", null: false + t.integer "quantity" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["character_id"], name: "index_character_items_on_character_id" + t.index ["item_id"], name: "index_character_items_on_item_id" + end + create_table "characters", force: :cascade do |t| t.string "name" t.bigint "user_id", null: false @@ -83,6 +93,8 @@ ActiveRecord::Schema.define(version: 2021_05_03_002720) do t.index ["unlock_token"], name: "index_users_on_unlock_token", unique: true end + add_foreign_key "character_items", "characters" + add_foreign_key "character_items", "items" add_foreign_key "characters", "activities" add_foreign_key "characters", "users" add_foreign_key "users", "characters", column: "active_character_id" diff --git a/test/fixtures/character_items.yml b/test/fixtures/character_items.yml new file mode 100644 index 0000000..67027fb --- /dev/null +++ b/test/fixtures/character_items.yml @@ -0,0 +1,11 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + character: one + item: one + quantity: 1 + +two: + character: two + item: two + quantity: 1 diff --git a/test/models/character_item_test.rb b/test/models/character_item_test.rb new file mode 100644 index 0000000..713730b --- /dev/null +++ b/test/models/character_item_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class CharacterItemTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end -- cgit v1.2.3