diff options
-rw-r--r-- | app/controllers/characters/items_controller.rb | 5 | ||||
-rw-r--r-- | app/errors/item_quantity_error.rb | 2 | ||||
-rw-r--r-- | app/models/character.rb | 10 | ||||
-rw-r--r-- | app/models/character_item.rb | 25 | ||||
-rw-r--r-- | app/views/application/_navbar.html.erb | 11 | ||||
-rw-r--r-- | app/views/characters/items/index.html.erb | 36 | ||||
-rw-r--r-- | config/routes.rb | 6 | ||||
-rw-r--r-- | db/migrate/20210503005919_create_character_items.rb | 11 | ||||
-rw-r--r-- | db/schema.rb | 14 | ||||
-rw-r--r-- | test/fixtures/character_items.yml | 11 | ||||
-rw-r--r-- | test/models/character_item_test.rb | 7 |
11 files changed, 129 insertions, 9 deletions
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 @@ <ul class="py-2 px-2 col-span-12 text-display"> - <% if user_signed_in? %> <%# Will replace this with `current_character` or equivalent, eventually %> + <% if current_char %> <li class="mr-6 inline"> - LinkA + Actions </li> <li class="mr-6 inline"> - LinkB + <%= link_to "Character", character_path(current_char) %> </li> <li class="mr-6 inline"> - LinkC - </li> - <li class="mr-6 inline"> - LinkD + <%= link_to "Inventory", character_items_path(current_char) %> </li> <% end %> </ul> 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 @@ +<h1 class="text-xl">Inventory</h1> + +<table class="table-auto"> + <thead> + <tr> + <th class="table-header-padded">Amount</th> + <th class="table-header-padded">Item</th> + <th class="table-header-padded">Equip</th> + <th class="table-header-padded">Use</th> + <th class="table-header-padded">Destroy</th> + </tr> + </thead> + <tbody> + <% @character_items.ordered_by_item_name.each do |ci| %> + <tr> + <td class="table-cell-padded text-right"><%= ci.quantity %></td> + <td class="table-cell-padded"><%= ci.item.name %></td> + <td class="table-cell-padded"> + <% if ci.item.equip_slot %> + <%= link_to "[Equip]", "#" %> + <% end %> + </td> + <td class="table-cell-padded"> + <% if ci.item.usable? %> + <%= link_to "[Use]", "#" %> + <% end %> + </td> + <td class="table-cell-padded"> + <%= link_to "[Destroy]", "#" %> + <%= link_to "[Destroy All]", "#" %> + </td> + </tr> + <% end %> + </tbody> +</table> + 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 |