From 98c2ba3b5a62b7aa88b0ab8bf29e2a7606b9abd6 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 9 Apr 2023 21:51:43 -0700 Subject: [PATCH 01/12] Fix a bug where unauthenticated users couldn't view profiles (#92) * Implements advanced filters (#90) (#91) * Add advanced filters Adds new filters to search: * Full auto * Charge attack * Auto guard * Number of weapons (user-selectable now) * Number of summons * Number of characters * Maximum number of turns * Maximum number of buttons * Maximum clear time * User quality (No anonymous users) * Name quality (No untitled teams) * Remixes (Only show original teams) * Update advanced filter params * Add default to party counter cache * Fix being unable to see profiles when unauth --- app/models/party.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/party.rb b/app/models/party.rb index 2dde088..8345471 100644 --- a/app/models/party.rb +++ b/app/models/party.rb @@ -84,7 +84,7 @@ class Party < ApplicationRecord attr_accessor :favorited def is_favorited(user) - user.favorite_parties.include? self + user.favorite_parties.include? self if user end def is_remix From 037f74d86df00a2b88693594c426841c6d015e2b Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 9 Apr 2023 21:52:16 -0700 Subject: [PATCH 02/12] Deploy unauthenticated profile fix (#93) * Implements advanced filters (#90) * Add advanced filters Adds new filters to search: * Full auto * Charge attack * Auto guard * Number of weapons (user-selectable now) * Number of summons * Number of characters * Maximum number of turns * Maximum number of buttons * Maximum clear time * User quality (No anonymous users) * Name quality (No untitled teams) * Remixes (Only show original teams) * Update advanced filter params * Add default to party counter cache * Fix a bug where unauthenticated users couldn't view profiles (#92) * Implements advanced filters (#90) (#91) * Add advanced filters Adds new filters to search: * Full auto * Charge attack * Auto guard * Number of weapons (user-selectable now) * Number of summons * Number of characters * Maximum number of turns * Maximum number of buttons * Maximum clear time * User quality (No anonymous users) * Name quality (No untitled teams) * Remixes (Only show original teams) * Update advanced filter params * Add default to party counter cache * Fix being unable to see profiles when unauth --- app/models/party.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/party.rb b/app/models/party.rb index 2dde088..8345471 100644 --- a/app/models/party.rb +++ b/app/models/party.rb @@ -84,7 +84,7 @@ class Party < ApplicationRecord attr_accessor :favorited def is_favorited(user) - user.favorite_parties.include? self + user.favorite_parties.include? self if user end def is_remix From 52b4b7452ea5cde635a0f4f0b1b50e1bea36191a Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Thu, 4 May 2023 12:59:31 -0700 Subject: [PATCH 03/12] Add tables used for Siero's revival (#94) * Implements advanced filters (#90) (#91) * Add advanced filters Adds new filters to search: * Full auto * Charge attack * Auto guard * Number of weapons (user-selectable now) * Number of summons * Number of characters * Maximum number of turns * Maximum number of buttons * Maximum clear time * User quality (No anonymous users) * Name quality (No untitled teams) * Remixes (Only show original teams) * Update advanced filter params * Add default to party counter cache * Deploy unauthenticated profile fix (#93) * Implements advanced filters (#90) * Add advanced filters Adds new filters to search: * Full auto * Charge attack * Auto guard * Number of weapons (user-selectable now) * Number of summons * Number of characters * Maximum number of turns * Maximum number of buttons * Maximum clear time * User quality (No anonymous users) * Name quality (No untitled teams) * Remixes (Only show original teams) * Update advanced filter params * Add default to party counter cache * Fix a bug where unauthenticated users couldn't view profiles (#92) * Implements advanced filters (#90) (#91) * Add advanced filters Adds new filters to search: * Full auto * Charge attack * Auto guard * Number of weapons (user-selectable now) * Number of summons * Number of characters * Maximum number of turns * Maximum number of buttons * Maximum clear time * User quality (No anonymous users) * Name quality (No untitled teams) * Remixes (Only show original teams) * Update advanced filter params * Add default to party counter cache * Fix being unable to see profiles when unauth * Add guidebooks migration * Implement business logic for reading Guidebooks * Change to individual guidebook columns * Properly output guidebook description * Move to 1-index guidebooks * Update party-related files for 1-index guidebooks * Add tables for Siero --- app/blueprints/api/v1/guidebook_blueprint.rb | 23 ++++++++ app/blueprints/api/v1/party_blueprint.rb | 8 +++ .../api/v1/guidebooks_controller.rb | 11 ++++ app/controllers/api/v1/parties_controller.rb | 9 ++- app/controllers/api/v1/search_controller.rb | 20 +++++++ app/models/guidebook.rb | 37 ++++++++++++ app/models/party.rb | 29 +++++++++ config/routes.rb | 3 + db/migrate/20230418052314_add_guidebooks.rb | 12 ++++ .../20230418052325_add_guidebooks_to_party.rb | 5 ++ ...30418061932_update_guidebooks_structure.rb | 6 ++ ...647_rename_guidebooks_to_guidebook_i_ds.rb | 5 ++ ...0230419033648_split_guidebooks_on_party.rb | 8 +++ ...20230419102354_rename_guidebook_columns.rb | 5 ++ db/migrate/20230423070004_add_gacha_table.rb | 13 ++++ .../20230423071446_add_recruits_to_weapon.rb | 5 ++ ...125524_change_gacha_drawable_id_to_uuid.rb | 7 +++ ...423132430_make_gacha_drawable_id_unique.rb | 5 ++ .../20230502012823_add_gacha_rateups_table.rb | 8 +++ db/migrate/20230503221903_add_sparks_table.rb | 11 ++++ ...0230503224345_add_target_memo_to_sparks.rb | 5 ++ ...503224353_make_user_id_unique_in_sparks.rb | 5 ++ db/schema.rb | 59 ++++++++++++++++++- 23 files changed, 295 insertions(+), 4 deletions(-) create mode 100644 app/blueprints/api/v1/guidebook_blueprint.rb create mode 100644 app/controllers/api/v1/guidebooks_controller.rb create mode 100644 app/models/guidebook.rb create mode 100644 db/migrate/20230418052314_add_guidebooks.rb create mode 100644 db/migrate/20230418052325_add_guidebooks_to_party.rb create mode 100644 db/migrate/20230418061932_update_guidebooks_structure.rb create mode 100644 db/migrate/20230418071647_rename_guidebooks_to_guidebook_i_ds.rb create mode 100644 db/migrate/20230419033648_split_guidebooks_on_party.rb create mode 100644 db/migrate/20230419102354_rename_guidebook_columns.rb create mode 100644 db/migrate/20230423070004_add_gacha_table.rb create mode 100644 db/migrate/20230423071446_add_recruits_to_weapon.rb create mode 100644 db/migrate/20230423125524_change_gacha_drawable_id_to_uuid.rb create mode 100644 db/migrate/20230423132430_make_gacha_drawable_id_unique.rb create mode 100644 db/migrate/20230502012823_add_gacha_rateups_table.rb create mode 100644 db/migrate/20230503221903_add_sparks_table.rb create mode 100644 db/migrate/20230503224345_add_target_memo_to_sparks.rb create mode 100644 db/migrate/20230503224353_make_user_id_unique_in_sparks.rb diff --git a/app/blueprints/api/v1/guidebook_blueprint.rb b/app/blueprints/api/v1/guidebook_blueprint.rb new file mode 100644 index 0000000..21536ac --- /dev/null +++ b/app/blueprints/api/v1/guidebook_blueprint.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Api + module V1 + class GuidebookBlueprint < ApiBlueprint + field :name do |book| + { + en: book.name_en, + ja: book.name_jp + } + end + + field :description do |book| + { + en: book.description_en, + ja: book.description_jp + } + end + + fields :granblue_id + end + end +end diff --git a/app/blueprints/api/v1/party_blueprint.rb b/app/blueprints/api/v1/party_blueprint.rb index 6b8e19f..fe6674d 100644 --- a/app/blueprints/api/v1/party_blueprint.rb +++ b/app/blueprints/api/v1/party_blueprint.rb @@ -40,6 +40,14 @@ module Api p.is_remix end + field :guidebooks do |p| + { + '1' => !p.guidebook1.nil? ? GuidebookBlueprint.render_as_hash(p.guidebook1) : nil, + '2' => !p.guidebook2.nil? ? GuidebookBlueprint.render_as_hash(p.guidebook2) : nil, + '3' => !p.guidebook3.nil? ? GuidebookBlueprint.render_as_hash(p.guidebook3) : nil + } + end + association :raid, blueprint: RaidBlueprint diff --git a/app/controllers/api/v1/guidebooks_controller.rb b/app/controllers/api/v1/guidebooks_controller.rb new file mode 100644 index 0000000..5d4cf8c --- /dev/null +++ b/app/controllers/api/v1/guidebooks_controller.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Api + module V1 + class GuidebooksController < Api::V1::ApiController + def all + render json: GuidebookBlueprint.render(Guidebook.all) + end + end + end +end diff --git a/app/controllers/api/v1/parties_controller.rb b/app/controllers/api/v1/parties_controller.rb index 5767706..8bbd66a 100644 --- a/app/controllers/api/v1/parties_controller.rb +++ b/app/controllers/api/v1/parties_controller.rb @@ -55,8 +55,8 @@ module Api # TODO: Validate accessory with job - return render json: PartyBlueprint.render(@party, view: :full, root: :party) if @party.save! - + return render json: PartyBlueprint.render(@party, view: :full, root: :party) if @party.save + render_validation_error_response(@party) end @@ -263,7 +263,10 @@ module Api :clear_time, :button_count, :turn_count, - :chain_count + :chain_count, + :guidebook1_id, + :guidebook2_id, + :guidebook3_id ) end end diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb index 336704f..0d94ae0 100644 --- a/app/controllers/api/v1/search_controller.rb +++ b/app/controllers/api/v1/search_controller.rb @@ -196,6 +196,26 @@ module Api }) end + def guidebooks + # Perform the query + books = if search_params[:query].present? && search_params[:query].length >= 2 + Guidebook.method("#{locale}_search").call(search_params[:query]) + else + Guidebook.all + end + + count = books.length + paginated = books.paginate(page: search_params[:page], per_page: SEARCH_PER_PAGE) + + render json: GuidebookBlueprint.render(paginated, + root: :results, + meta: { + count: count, + total_pages: total_pages(count), + per_page: SEARCH_PER_PAGE + }) + end + private def total_pages(count) diff --git a/app/models/guidebook.rb b/app/models/guidebook.rb new file mode 100644 index 0000000..581068a --- /dev/null +++ b/app/models/guidebook.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +class Guidebook < ApplicationRecord + alias eql? == + + include PgSearch::Model + + pg_search_scope :en_search, + against: :name_en, + using: { + tsearch: { + prefix: true, + dictionary: 'simple' + } + } + + pg_search_scope :jp_search, + against: :name_jp, + using: { + tsearch: { + prefix: true, + dictionary: 'simple' + } + } + + def blueprint + GuidebookBlueprint + end + + def display_resource(book) + book.name_en + end + + def ==(other) + self.class == other.class && granblue_id === other.granblue_id + end +end diff --git a/app/models/party.rb b/app/models/party.rb index 8345471..5729698 100644 --- a/app/models/party.rb +++ b/app/models/party.rb @@ -41,6 +41,21 @@ class Party < ApplicationRecord class_name: 'JobSkill', optional: true + belongs_to :guidebook1, + foreign_key: 'guidebook1_id', + class_name: 'Guidebook', + optional: true + + belongs_to :guidebook2, + foreign_key: 'guidebook2_id', + class_name: 'Guidebook', + optional: true + + belongs_to :guidebook3, + foreign_key: 'guidebook3_id', + class_name: 'Guidebook', + optional: true + has_many :characters, foreign_key: 'party_id', class_name: 'GridCharacter', @@ -80,6 +95,7 @@ class Party < ApplicationRecord ##### ActiveRecord Validations validate :skills_are_unique + validate :guidebooks_are_unique attr_accessor :favorited @@ -130,4 +146,17 @@ class Party < ApplicationRecord errors.add(:job_skills, 'must be unique') end + + def guidebooks_are_unique + guidebooks = [guidebook1, guidebook2, guidebook3].compact + return if guidebooks.uniq.length == guidebooks.length + + guidebooks.each_with_index do |book, index| + next if index.zero? + + errors.add(:"guidebook#{index + 1}", 'must be unique') if guidebooks[0...index].include?(book) + end + + errors.add(:guidebooks, 'must be unique') + end end diff --git a/config/routes.rb b/config/routes.rb index fe827c9..9218e0f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -34,6 +34,7 @@ Rails.application.routes.draw do post 'search/weapons', to: 'search#weapons' post 'search/summons', to: 'search#summons' post 'search/job_skills', to: 'search#job_skills' + post 'search/guidebooks', to: 'search#guidebooks' get 'jobs', to: 'jobs#all' @@ -41,6 +42,8 @@ Rails.application.routes.draw do get 'jobs/:id/skills', to: 'job_skills#job' get 'jobs/:id/accessories', to: 'job_accessories#job' + get 'guidebooks', to: 'guidebooks#all' + get 'raids', to: 'raids#all' get 'weapon_keys', to: 'weapon_keys#all' diff --git a/db/migrate/20230418052314_add_guidebooks.rb b/db/migrate/20230418052314_add_guidebooks.rb new file mode 100644 index 0000000..c74e306 --- /dev/null +++ b/db/migrate/20230418052314_add_guidebooks.rb @@ -0,0 +1,12 @@ +class AddGuidebooks < ActiveRecord::Migration[7.0] + def change + create_table :guidebooks, id: :uuid, default: -> { "gen_random_uuid()" } do |t| + t.string :granblue_id, null: false, unique: true + t.string :name_en, null: false, unique: true + t.string :name_jp, null: false, unique: true + t.string :description_en, null: false + t.string :description_jp, null: false + t.timestamps + end + end +end diff --git a/db/migrate/20230418052325_add_guidebooks_to_party.rb b/db/migrate/20230418052325_add_guidebooks_to_party.rb new file mode 100644 index 0000000..9c05639 --- /dev/null +++ b/db/migrate/20230418052325_add_guidebooks_to_party.rb @@ -0,0 +1,5 @@ +class AddGuidebooksToParty < ActiveRecord::Migration[7.0] + def change + add_column :parties, :guidebooks, :uuid, array: true, default: [], null: false + end +end diff --git a/db/migrate/20230418061932_update_guidebooks_structure.rb b/db/migrate/20230418061932_update_guidebooks_structure.rb new file mode 100644 index 0000000..c7005df --- /dev/null +++ b/db/migrate/20230418061932_update_guidebooks_structure.rb @@ -0,0 +1,6 @@ +class UpdateGuidebooksStructure < ActiveRecord::Migration[7.0] + def change + remove_column :guidebooks, :updated_at + change_column_default :guidebooks, :created_at, -> { 'CURRENT_TIMESTAMP' } + end +end diff --git a/db/migrate/20230418071647_rename_guidebooks_to_guidebook_i_ds.rb b/db/migrate/20230418071647_rename_guidebooks_to_guidebook_i_ds.rb new file mode 100644 index 0000000..7b80062 --- /dev/null +++ b/db/migrate/20230418071647_rename_guidebooks_to_guidebook_i_ds.rb @@ -0,0 +1,5 @@ +class RenameGuidebooksToGuidebookIDs < ActiveRecord::Migration[7.0] + def change + rename_column :parties, :guidebooks, :guidebook_ids + end +end diff --git a/db/migrate/20230419033648_split_guidebooks_on_party.rb b/db/migrate/20230419033648_split_guidebooks_on_party.rb new file mode 100644 index 0000000..08dc2d2 --- /dev/null +++ b/db/migrate/20230419033648_split_guidebooks_on_party.rb @@ -0,0 +1,8 @@ +class SplitGuidebooksOnParty < ActiveRecord::Migration[7.0] + def change + remove_column :parties, :guidebook_ids + add_reference :parties, :guidebook0, type: :uuid, foreign_key: { to_table: :guidebooks } + add_reference :parties, :guidebook1, type: :uuid, foreign_key: { to_table: :guidebooks } + add_reference :parties, :guidebook2, type: :uuid, foreign_key: { to_table: :guidebooks } + end +end diff --git a/db/migrate/20230419102354_rename_guidebook_columns.rb b/db/migrate/20230419102354_rename_guidebook_columns.rb new file mode 100644 index 0000000..f7116f6 --- /dev/null +++ b/db/migrate/20230419102354_rename_guidebook_columns.rb @@ -0,0 +1,5 @@ +class RenameGuidebookColumns < ActiveRecord::Migration[7.0] + def change + rename_column :parties, :guidebook0_id, :guidebook3_id + end +end diff --git a/db/migrate/20230423070004_add_gacha_table.rb b/db/migrate/20230423070004_add_gacha_table.rb new file mode 100644 index 0000000..264051a --- /dev/null +++ b/db/migrate/20230423070004_add_gacha_table.rb @@ -0,0 +1,13 @@ +class AddGachaTable < ActiveRecord::Migration[7.0] + create_table :gacha, id: :uuid, default: -> { "gen_random_uuid()" } do |t| + t.references :drawable, polymorphic: true + t.boolean :premium + t.boolean :classic + t.boolean :flash + t.boolean :legend + t.boolean :valentines + t.boolean :summer + t.boolean :halloween + t.boolean :holiday + end +end diff --git a/db/migrate/20230423071446_add_recruits_to_weapon.rb b/db/migrate/20230423071446_add_recruits_to_weapon.rb new file mode 100644 index 0000000..21dbf1e --- /dev/null +++ b/db/migrate/20230423071446_add_recruits_to_weapon.rb @@ -0,0 +1,5 @@ +class AddRecruitsToWeapon < ActiveRecord::Migration[7.0] + def change + add_reference :weapons, :recruits, null: true, to_table: 'character_id', type: :uuid + end +end diff --git a/db/migrate/20230423125524_change_gacha_drawable_id_to_uuid.rb b/db/migrate/20230423125524_change_gacha_drawable_id_to_uuid.rb new file mode 100644 index 0000000..e274ffe --- /dev/null +++ b/db/migrate/20230423125524_change_gacha_drawable_id_to_uuid.rb @@ -0,0 +1,7 @@ +class ChangeGachaDrawableIdToUuid < ActiveRecord::Migration[7.0] + def change + remove_column :gacha, :drawable_id, :bigint + remove_column :gacha, :drawable_type, :string + add_reference :gacha, :drawable, polymorphic: true, type: :uuid + end +end diff --git a/db/migrate/20230423132430_make_gacha_drawable_id_unique.rb b/db/migrate/20230423132430_make_gacha_drawable_id_unique.rb new file mode 100644 index 0000000..3181999 --- /dev/null +++ b/db/migrate/20230423132430_make_gacha_drawable_id_unique.rb @@ -0,0 +1,5 @@ +class MakeGachaDrawableIdUnique < ActiveRecord::Migration[7.0] + def change + add_index :gacha, :drawable_id, unique: true + end +end diff --git a/db/migrate/20230502012823_add_gacha_rateups_table.rb b/db/migrate/20230502012823_add_gacha_rateups_table.rb new file mode 100644 index 0000000..da7c72f --- /dev/null +++ b/db/migrate/20230502012823_add_gacha_rateups_table.rb @@ -0,0 +1,8 @@ +class AddGachaRateupsTable < ActiveRecord::Migration[7.0] + create_table :gacha_rateups, id: :uuid, default: -> { "gen_random_uuid()" } do |t| + t.references :gacha, type: :uuid + t.string :user_id + t.numeric :rate + t.datetime :created_at, null: false, default: -> { 'CURRENT_TIMESTAMP' } + end +end diff --git a/db/migrate/20230503221903_add_sparks_table.rb b/db/migrate/20230503221903_add_sparks_table.rb new file mode 100644 index 0000000..fca83e0 --- /dev/null +++ b/db/migrate/20230503221903_add_sparks_table.rb @@ -0,0 +1,11 @@ +class AddSparksTable < ActiveRecord::Migration[7.0] + create_table :sparks, id: :uuid, default: -> { "gen_random_uuid()" } do |t| + t.string :user_id, null: false + t.string :guild_ids, array: true, null: false + t.integer :crystals, default: 0 + t.integer :tickets, default: 0 + t.integer :ten_tickets, default: 0 + t.references :target, polymorphic: true + t.datetime :updated_at, null: false, default: -> { 'CURRENT_TIMESTAMP' } + end +end diff --git a/db/migrate/20230503224345_add_target_memo_to_sparks.rb b/db/migrate/20230503224345_add_target_memo_to_sparks.rb new file mode 100644 index 0000000..c31caea --- /dev/null +++ b/db/migrate/20230503224345_add_target_memo_to_sparks.rb @@ -0,0 +1,5 @@ +class AddTargetMemoToSparks < ActiveRecord::Migration[7.0] + def change + add_column :sparks, :target_memo, :string + end +end diff --git a/db/migrate/20230503224353_make_user_id_unique_in_sparks.rb b/db/migrate/20230503224353_make_user_id_unique_in_sparks.rb new file mode 100644 index 0000000..16ffff6 --- /dev/null +++ b/db/migrate/20230503224353_make_user_id_unique_in_sparks.rb @@ -0,0 +1,5 @@ +class MakeUserIdUniqueInSparks < ActiveRecord::Migration[7.0] + def change + add_index :sparks, :user_id, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index b0dc946..ad74e64 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[7.0].define(version: 2023_03_21_115930) do +ActiveRecord::Schema[7.0].define(version: 2023_05_03_224353) do # These are extensions that must be enabled in order to support this database enable_extension "btree_gin" enable_extension "pg_trgm" @@ -124,6 +124,29 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_21_115930) do t.index ["user_id"], name: "index_favorites_on_user_id" end + create_table "gacha", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.boolean "premium" + t.boolean "classic" + t.boolean "flash" + t.boolean "legend" + t.boolean "valentines" + t.boolean "summer" + t.boolean "halloween" + t.boolean "holiday" + t.string "drawable_type" + t.uuid "drawable_id" + t.index ["drawable_id"], name: "index_gacha_on_drawable_id", unique: true + t.index ["drawable_type", "drawable_id"], name: "index_gacha_on_drawable" + end + + create_table "gacha_rateups", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.uuid "gacha_id" + t.string "user_id" + t.decimal "rate" + t.datetime "created_at", default: -> { "CURRENT_TIMESTAMP" }, null: false + t.index ["gacha_id"], name: "index_gacha_rateups_on_gacha_id" + end + create_table "grid_characters", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "party_id" t.uuid "character_id" @@ -187,6 +210,15 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_21_115930) do t.index ["weapon_key3_id"], name: "index_grid_weapons_on_weapon_key3_id" end + create_table "guidebooks", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.string "granblue_id", null: false + t.string "name_en", null: false + t.string "name_jp", null: false + t.string "description_en", null: false + t.string "description_jp", null: false + t.datetime "created_at", default: -> { "CURRENT_TIMESTAMP" }, null: false + end + create_table "job_accessories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "job_id" t.string "name_en", null: false @@ -297,7 +329,13 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_21_115930) do t.string "edit_key" t.uuid "local_id" t.integer "ultimate_mastery" + t.uuid "guidebook3_id" + t.uuid "guidebook1_id" + t.uuid "guidebook2_id" t.index ["accessory_id"], name: "index_parties_on_accessory_id" + t.index ["guidebook1_id"], name: "index_parties_on_guidebook1_id" + t.index ["guidebook2_id"], name: "index_parties_on_guidebook2_id" + t.index ["guidebook3_id"], name: "index_parties_on_guidebook3_id" t.index ["job_id"], name: "index_parties_on_job_id" t.index ["skill0_id"], name: "index_parties_on_skill0_id" t.index ["skill1_id"], name: "index_parties_on_skill1_id" @@ -316,6 +354,20 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_21_115930) do t.string "slug" end + create_table "sparks", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.string "user_id", null: false + t.string "guild_ids", null: false, array: true + t.integer "crystals", default: 0 + t.integer "tickets", default: 0 + t.integer "ten_tickets", default: 0 + t.string "target_type" + t.bigint "target_id" + t.datetime "updated_at", default: -> { "CURRENT_TIMESTAMP" }, null: false + t.string "target_memo" + t.index ["target_type", "target_id"], name: "index_sparks_on_target" + t.index ["user_id"], name: "index_sparks_on_user_id", unique: true + end + create_table "summons", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.string "name_en" t.string "name_jp" @@ -398,7 +450,9 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_21_115930) do t.integer "awakening_types", default: [], array: true t.string "nicknames_en", default: [], null: false, array: true t.string "nicknames_jp", default: [], null: false, array: true + t.uuid "recruits_id" t.index ["name_en"], name: "index_weapons_on_name_en", opclass: :gin_trgm_ops, using: :gin + t.index ["recruits_id"], name: "index_weapons_on_recruits_id" end add_foreign_key "favorites", "parties" @@ -413,6 +467,9 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_21_115930) do add_foreign_key "jobs", "jobs", column: "base_job_id" add_foreign_key "oauth_access_grants", "oauth_applications", column: "application_id" add_foreign_key "oauth_access_tokens", "oauth_applications", column: "application_id" + add_foreign_key "parties", "guidebooks", column: "guidebook1_id" + add_foreign_key "parties", "guidebooks", column: "guidebook2_id" + add_foreign_key "parties", "guidebooks", column: "guidebook3_id" add_foreign_key "parties", "job_accessories", column: "accessory_id" add_foreign_key "parties", "job_skills", column: "skill0_id" add_foreign_key "parties", "job_skills", column: "skill1_id" From af8b1aa9c11df259d436a3adfd6adfdb21044e1e Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 4 Jun 2023 22:23:34 -0700 Subject: [PATCH 04/12] Adds guidebooks and gacha tables (#95) * Implements advanced filters (#90) * Add advanced filters Adds new filters to search: * Full auto * Charge attack * Auto guard * Number of weapons (user-selectable now) * Number of summons * Number of characters * Maximum number of turns * Maximum number of buttons * Maximum clear time * User quality (No anonymous users) * Name quality (No untitled teams) * Remixes (Only show original teams) * Update advanced filter params * Add default to party counter cache * Fix a bug where unauthenticated users couldn't view profiles (#92) * Implements advanced filters (#90) (#91) * Add advanced filters Adds new filters to search: * Full auto * Charge attack * Auto guard * Number of weapons (user-selectable now) * Number of summons * Number of characters * Maximum number of turns * Maximum number of buttons * Maximum clear time * User quality (No anonymous users) * Name quality (No untitled teams) * Remixes (Only show original teams) * Update advanced filter params * Add default to party counter cache * Fix being unable to see profiles when unauth * Add tables used for Siero's revival (#94) * Implements advanced filters (#90) (#91) * Add advanced filters Adds new filters to search: * Full auto * Charge attack * Auto guard * Number of weapons (user-selectable now) * Number of summons * Number of characters * Maximum number of turns * Maximum number of buttons * Maximum clear time * User quality (No anonymous users) * Name quality (No untitled teams) * Remixes (Only show original teams) * Update advanced filter params * Add default to party counter cache * Deploy unauthenticated profile fix (#93) * Implements advanced filters (#90) * Add advanced filters Adds new filters to search: * Full auto * Charge attack * Auto guard * Number of weapons (user-selectable now) * Number of summons * Number of characters * Maximum number of turns * Maximum number of buttons * Maximum clear time * User quality (No anonymous users) * Name quality (No untitled teams) * Remixes (Only show original teams) * Update advanced filter params * Add default to party counter cache * Fix a bug where unauthenticated users couldn't view profiles (#92) * Implements advanced filters (#90) (#91) * Add advanced filters Adds new filters to search: * Full auto * Charge attack * Auto guard * Number of weapons (user-selectable now) * Number of summons * Number of characters * Maximum number of turns * Maximum number of buttons * Maximum clear time * User quality (No anonymous users) * Name quality (No untitled teams) * Remixes (Only show original teams) * Update advanced filter params * Add default to party counter cache * Fix being unable to see profiles when unauth * Add guidebooks migration * Implement business logic for reading Guidebooks * Change to individual guidebook columns * Properly output guidebook description * Move to 1-index guidebooks * Update party-related files for 1-index guidebooks * Add tables for Siero --- app/blueprints/api/v1/guidebook_blueprint.rb | 23 ++++++++ app/blueprints/api/v1/party_blueprint.rb | 8 +++ .../api/v1/guidebooks_controller.rb | 11 ++++ app/controllers/api/v1/parties_controller.rb | 9 ++- app/controllers/api/v1/search_controller.rb | 20 +++++++ app/models/guidebook.rb | 37 ++++++++++++ app/models/party.rb | 29 +++++++++ config/routes.rb | 3 + db/migrate/20230418052314_add_guidebooks.rb | 12 ++++ .../20230418052325_add_guidebooks_to_party.rb | 5 ++ ...30418061932_update_guidebooks_structure.rb | 6 ++ ...647_rename_guidebooks_to_guidebook_i_ds.rb | 5 ++ ...0230419033648_split_guidebooks_on_party.rb | 8 +++ ...20230419102354_rename_guidebook_columns.rb | 5 ++ db/migrate/20230423070004_add_gacha_table.rb | 13 ++++ .../20230423071446_add_recruits_to_weapon.rb | 5 ++ ...125524_change_gacha_drawable_id_to_uuid.rb | 7 +++ ...423132430_make_gacha_drawable_id_unique.rb | 5 ++ .../20230502012823_add_gacha_rateups_table.rb | 8 +++ db/migrate/20230503221903_add_sparks_table.rb | 11 ++++ ...0230503224345_add_target_memo_to_sparks.rb | 5 ++ ...503224353_make_user_id_unique_in_sparks.rb | 5 ++ db/schema.rb | 59 ++++++++++++++++++- 23 files changed, 295 insertions(+), 4 deletions(-) create mode 100644 app/blueprints/api/v1/guidebook_blueprint.rb create mode 100644 app/controllers/api/v1/guidebooks_controller.rb create mode 100644 app/models/guidebook.rb create mode 100644 db/migrate/20230418052314_add_guidebooks.rb create mode 100644 db/migrate/20230418052325_add_guidebooks_to_party.rb create mode 100644 db/migrate/20230418061932_update_guidebooks_structure.rb create mode 100644 db/migrate/20230418071647_rename_guidebooks_to_guidebook_i_ds.rb create mode 100644 db/migrate/20230419033648_split_guidebooks_on_party.rb create mode 100644 db/migrate/20230419102354_rename_guidebook_columns.rb create mode 100644 db/migrate/20230423070004_add_gacha_table.rb create mode 100644 db/migrate/20230423071446_add_recruits_to_weapon.rb create mode 100644 db/migrate/20230423125524_change_gacha_drawable_id_to_uuid.rb create mode 100644 db/migrate/20230423132430_make_gacha_drawable_id_unique.rb create mode 100644 db/migrate/20230502012823_add_gacha_rateups_table.rb create mode 100644 db/migrate/20230503221903_add_sparks_table.rb create mode 100644 db/migrate/20230503224345_add_target_memo_to_sparks.rb create mode 100644 db/migrate/20230503224353_make_user_id_unique_in_sparks.rb diff --git a/app/blueprints/api/v1/guidebook_blueprint.rb b/app/blueprints/api/v1/guidebook_blueprint.rb new file mode 100644 index 0000000..21536ac --- /dev/null +++ b/app/blueprints/api/v1/guidebook_blueprint.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Api + module V1 + class GuidebookBlueprint < ApiBlueprint + field :name do |book| + { + en: book.name_en, + ja: book.name_jp + } + end + + field :description do |book| + { + en: book.description_en, + ja: book.description_jp + } + end + + fields :granblue_id + end + end +end diff --git a/app/blueprints/api/v1/party_blueprint.rb b/app/blueprints/api/v1/party_blueprint.rb index 6b8e19f..fe6674d 100644 --- a/app/blueprints/api/v1/party_blueprint.rb +++ b/app/blueprints/api/v1/party_blueprint.rb @@ -40,6 +40,14 @@ module Api p.is_remix end + field :guidebooks do |p| + { + '1' => !p.guidebook1.nil? ? GuidebookBlueprint.render_as_hash(p.guidebook1) : nil, + '2' => !p.guidebook2.nil? ? GuidebookBlueprint.render_as_hash(p.guidebook2) : nil, + '3' => !p.guidebook3.nil? ? GuidebookBlueprint.render_as_hash(p.guidebook3) : nil + } + end + association :raid, blueprint: RaidBlueprint diff --git a/app/controllers/api/v1/guidebooks_controller.rb b/app/controllers/api/v1/guidebooks_controller.rb new file mode 100644 index 0000000..5d4cf8c --- /dev/null +++ b/app/controllers/api/v1/guidebooks_controller.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Api + module V1 + class GuidebooksController < Api::V1::ApiController + def all + render json: GuidebookBlueprint.render(Guidebook.all) + end + end + end +end diff --git a/app/controllers/api/v1/parties_controller.rb b/app/controllers/api/v1/parties_controller.rb index 5767706..8bbd66a 100644 --- a/app/controllers/api/v1/parties_controller.rb +++ b/app/controllers/api/v1/parties_controller.rb @@ -55,8 +55,8 @@ module Api # TODO: Validate accessory with job - return render json: PartyBlueprint.render(@party, view: :full, root: :party) if @party.save! - + return render json: PartyBlueprint.render(@party, view: :full, root: :party) if @party.save + render_validation_error_response(@party) end @@ -263,7 +263,10 @@ module Api :clear_time, :button_count, :turn_count, - :chain_count + :chain_count, + :guidebook1_id, + :guidebook2_id, + :guidebook3_id ) end end diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb index 336704f..0d94ae0 100644 --- a/app/controllers/api/v1/search_controller.rb +++ b/app/controllers/api/v1/search_controller.rb @@ -196,6 +196,26 @@ module Api }) end + def guidebooks + # Perform the query + books = if search_params[:query].present? && search_params[:query].length >= 2 + Guidebook.method("#{locale}_search").call(search_params[:query]) + else + Guidebook.all + end + + count = books.length + paginated = books.paginate(page: search_params[:page], per_page: SEARCH_PER_PAGE) + + render json: GuidebookBlueprint.render(paginated, + root: :results, + meta: { + count: count, + total_pages: total_pages(count), + per_page: SEARCH_PER_PAGE + }) + end + private def total_pages(count) diff --git a/app/models/guidebook.rb b/app/models/guidebook.rb new file mode 100644 index 0000000..581068a --- /dev/null +++ b/app/models/guidebook.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +class Guidebook < ApplicationRecord + alias eql? == + + include PgSearch::Model + + pg_search_scope :en_search, + against: :name_en, + using: { + tsearch: { + prefix: true, + dictionary: 'simple' + } + } + + pg_search_scope :jp_search, + against: :name_jp, + using: { + tsearch: { + prefix: true, + dictionary: 'simple' + } + } + + def blueprint + GuidebookBlueprint + end + + def display_resource(book) + book.name_en + end + + def ==(other) + self.class == other.class && granblue_id === other.granblue_id + end +end diff --git a/app/models/party.rb b/app/models/party.rb index 8345471..5729698 100644 --- a/app/models/party.rb +++ b/app/models/party.rb @@ -41,6 +41,21 @@ class Party < ApplicationRecord class_name: 'JobSkill', optional: true + belongs_to :guidebook1, + foreign_key: 'guidebook1_id', + class_name: 'Guidebook', + optional: true + + belongs_to :guidebook2, + foreign_key: 'guidebook2_id', + class_name: 'Guidebook', + optional: true + + belongs_to :guidebook3, + foreign_key: 'guidebook3_id', + class_name: 'Guidebook', + optional: true + has_many :characters, foreign_key: 'party_id', class_name: 'GridCharacter', @@ -80,6 +95,7 @@ class Party < ApplicationRecord ##### ActiveRecord Validations validate :skills_are_unique + validate :guidebooks_are_unique attr_accessor :favorited @@ -130,4 +146,17 @@ class Party < ApplicationRecord errors.add(:job_skills, 'must be unique') end + + def guidebooks_are_unique + guidebooks = [guidebook1, guidebook2, guidebook3].compact + return if guidebooks.uniq.length == guidebooks.length + + guidebooks.each_with_index do |book, index| + next if index.zero? + + errors.add(:"guidebook#{index + 1}", 'must be unique') if guidebooks[0...index].include?(book) + end + + errors.add(:guidebooks, 'must be unique') + end end diff --git a/config/routes.rb b/config/routes.rb index fe827c9..9218e0f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -34,6 +34,7 @@ Rails.application.routes.draw do post 'search/weapons', to: 'search#weapons' post 'search/summons', to: 'search#summons' post 'search/job_skills', to: 'search#job_skills' + post 'search/guidebooks', to: 'search#guidebooks' get 'jobs', to: 'jobs#all' @@ -41,6 +42,8 @@ Rails.application.routes.draw do get 'jobs/:id/skills', to: 'job_skills#job' get 'jobs/:id/accessories', to: 'job_accessories#job' + get 'guidebooks', to: 'guidebooks#all' + get 'raids', to: 'raids#all' get 'weapon_keys', to: 'weapon_keys#all' diff --git a/db/migrate/20230418052314_add_guidebooks.rb b/db/migrate/20230418052314_add_guidebooks.rb new file mode 100644 index 0000000..c74e306 --- /dev/null +++ b/db/migrate/20230418052314_add_guidebooks.rb @@ -0,0 +1,12 @@ +class AddGuidebooks < ActiveRecord::Migration[7.0] + def change + create_table :guidebooks, id: :uuid, default: -> { "gen_random_uuid()" } do |t| + t.string :granblue_id, null: false, unique: true + t.string :name_en, null: false, unique: true + t.string :name_jp, null: false, unique: true + t.string :description_en, null: false + t.string :description_jp, null: false + t.timestamps + end + end +end diff --git a/db/migrate/20230418052325_add_guidebooks_to_party.rb b/db/migrate/20230418052325_add_guidebooks_to_party.rb new file mode 100644 index 0000000..9c05639 --- /dev/null +++ b/db/migrate/20230418052325_add_guidebooks_to_party.rb @@ -0,0 +1,5 @@ +class AddGuidebooksToParty < ActiveRecord::Migration[7.0] + def change + add_column :parties, :guidebooks, :uuid, array: true, default: [], null: false + end +end diff --git a/db/migrate/20230418061932_update_guidebooks_structure.rb b/db/migrate/20230418061932_update_guidebooks_structure.rb new file mode 100644 index 0000000..c7005df --- /dev/null +++ b/db/migrate/20230418061932_update_guidebooks_structure.rb @@ -0,0 +1,6 @@ +class UpdateGuidebooksStructure < ActiveRecord::Migration[7.0] + def change + remove_column :guidebooks, :updated_at + change_column_default :guidebooks, :created_at, -> { 'CURRENT_TIMESTAMP' } + end +end diff --git a/db/migrate/20230418071647_rename_guidebooks_to_guidebook_i_ds.rb b/db/migrate/20230418071647_rename_guidebooks_to_guidebook_i_ds.rb new file mode 100644 index 0000000..7b80062 --- /dev/null +++ b/db/migrate/20230418071647_rename_guidebooks_to_guidebook_i_ds.rb @@ -0,0 +1,5 @@ +class RenameGuidebooksToGuidebookIDs < ActiveRecord::Migration[7.0] + def change + rename_column :parties, :guidebooks, :guidebook_ids + end +end diff --git a/db/migrate/20230419033648_split_guidebooks_on_party.rb b/db/migrate/20230419033648_split_guidebooks_on_party.rb new file mode 100644 index 0000000..08dc2d2 --- /dev/null +++ b/db/migrate/20230419033648_split_guidebooks_on_party.rb @@ -0,0 +1,8 @@ +class SplitGuidebooksOnParty < ActiveRecord::Migration[7.0] + def change + remove_column :parties, :guidebook_ids + add_reference :parties, :guidebook0, type: :uuid, foreign_key: { to_table: :guidebooks } + add_reference :parties, :guidebook1, type: :uuid, foreign_key: { to_table: :guidebooks } + add_reference :parties, :guidebook2, type: :uuid, foreign_key: { to_table: :guidebooks } + end +end diff --git a/db/migrate/20230419102354_rename_guidebook_columns.rb b/db/migrate/20230419102354_rename_guidebook_columns.rb new file mode 100644 index 0000000..f7116f6 --- /dev/null +++ b/db/migrate/20230419102354_rename_guidebook_columns.rb @@ -0,0 +1,5 @@ +class RenameGuidebookColumns < ActiveRecord::Migration[7.0] + def change + rename_column :parties, :guidebook0_id, :guidebook3_id + end +end diff --git a/db/migrate/20230423070004_add_gacha_table.rb b/db/migrate/20230423070004_add_gacha_table.rb new file mode 100644 index 0000000..264051a --- /dev/null +++ b/db/migrate/20230423070004_add_gacha_table.rb @@ -0,0 +1,13 @@ +class AddGachaTable < ActiveRecord::Migration[7.0] + create_table :gacha, id: :uuid, default: -> { "gen_random_uuid()" } do |t| + t.references :drawable, polymorphic: true + t.boolean :premium + t.boolean :classic + t.boolean :flash + t.boolean :legend + t.boolean :valentines + t.boolean :summer + t.boolean :halloween + t.boolean :holiday + end +end diff --git a/db/migrate/20230423071446_add_recruits_to_weapon.rb b/db/migrate/20230423071446_add_recruits_to_weapon.rb new file mode 100644 index 0000000..21dbf1e --- /dev/null +++ b/db/migrate/20230423071446_add_recruits_to_weapon.rb @@ -0,0 +1,5 @@ +class AddRecruitsToWeapon < ActiveRecord::Migration[7.0] + def change + add_reference :weapons, :recruits, null: true, to_table: 'character_id', type: :uuid + end +end diff --git a/db/migrate/20230423125524_change_gacha_drawable_id_to_uuid.rb b/db/migrate/20230423125524_change_gacha_drawable_id_to_uuid.rb new file mode 100644 index 0000000..e274ffe --- /dev/null +++ b/db/migrate/20230423125524_change_gacha_drawable_id_to_uuid.rb @@ -0,0 +1,7 @@ +class ChangeGachaDrawableIdToUuid < ActiveRecord::Migration[7.0] + def change + remove_column :gacha, :drawable_id, :bigint + remove_column :gacha, :drawable_type, :string + add_reference :gacha, :drawable, polymorphic: true, type: :uuid + end +end diff --git a/db/migrate/20230423132430_make_gacha_drawable_id_unique.rb b/db/migrate/20230423132430_make_gacha_drawable_id_unique.rb new file mode 100644 index 0000000..3181999 --- /dev/null +++ b/db/migrate/20230423132430_make_gacha_drawable_id_unique.rb @@ -0,0 +1,5 @@ +class MakeGachaDrawableIdUnique < ActiveRecord::Migration[7.0] + def change + add_index :gacha, :drawable_id, unique: true + end +end diff --git a/db/migrate/20230502012823_add_gacha_rateups_table.rb b/db/migrate/20230502012823_add_gacha_rateups_table.rb new file mode 100644 index 0000000..da7c72f --- /dev/null +++ b/db/migrate/20230502012823_add_gacha_rateups_table.rb @@ -0,0 +1,8 @@ +class AddGachaRateupsTable < ActiveRecord::Migration[7.0] + create_table :gacha_rateups, id: :uuid, default: -> { "gen_random_uuid()" } do |t| + t.references :gacha, type: :uuid + t.string :user_id + t.numeric :rate + t.datetime :created_at, null: false, default: -> { 'CURRENT_TIMESTAMP' } + end +end diff --git a/db/migrate/20230503221903_add_sparks_table.rb b/db/migrate/20230503221903_add_sparks_table.rb new file mode 100644 index 0000000..fca83e0 --- /dev/null +++ b/db/migrate/20230503221903_add_sparks_table.rb @@ -0,0 +1,11 @@ +class AddSparksTable < ActiveRecord::Migration[7.0] + create_table :sparks, id: :uuid, default: -> { "gen_random_uuid()" } do |t| + t.string :user_id, null: false + t.string :guild_ids, array: true, null: false + t.integer :crystals, default: 0 + t.integer :tickets, default: 0 + t.integer :ten_tickets, default: 0 + t.references :target, polymorphic: true + t.datetime :updated_at, null: false, default: -> { 'CURRENT_TIMESTAMP' } + end +end diff --git a/db/migrate/20230503224345_add_target_memo_to_sparks.rb b/db/migrate/20230503224345_add_target_memo_to_sparks.rb new file mode 100644 index 0000000..c31caea --- /dev/null +++ b/db/migrate/20230503224345_add_target_memo_to_sparks.rb @@ -0,0 +1,5 @@ +class AddTargetMemoToSparks < ActiveRecord::Migration[7.0] + def change + add_column :sparks, :target_memo, :string + end +end diff --git a/db/migrate/20230503224353_make_user_id_unique_in_sparks.rb b/db/migrate/20230503224353_make_user_id_unique_in_sparks.rb new file mode 100644 index 0000000..16ffff6 --- /dev/null +++ b/db/migrate/20230503224353_make_user_id_unique_in_sparks.rb @@ -0,0 +1,5 @@ +class MakeUserIdUniqueInSparks < ActiveRecord::Migration[7.0] + def change + add_index :sparks, :user_id, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index b0dc946..ad74e64 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[7.0].define(version: 2023_03_21_115930) do +ActiveRecord::Schema[7.0].define(version: 2023_05_03_224353) do # These are extensions that must be enabled in order to support this database enable_extension "btree_gin" enable_extension "pg_trgm" @@ -124,6 +124,29 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_21_115930) do t.index ["user_id"], name: "index_favorites_on_user_id" end + create_table "gacha", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.boolean "premium" + t.boolean "classic" + t.boolean "flash" + t.boolean "legend" + t.boolean "valentines" + t.boolean "summer" + t.boolean "halloween" + t.boolean "holiday" + t.string "drawable_type" + t.uuid "drawable_id" + t.index ["drawable_id"], name: "index_gacha_on_drawable_id", unique: true + t.index ["drawable_type", "drawable_id"], name: "index_gacha_on_drawable" + end + + create_table "gacha_rateups", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.uuid "gacha_id" + t.string "user_id" + t.decimal "rate" + t.datetime "created_at", default: -> { "CURRENT_TIMESTAMP" }, null: false + t.index ["gacha_id"], name: "index_gacha_rateups_on_gacha_id" + end + create_table "grid_characters", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "party_id" t.uuid "character_id" @@ -187,6 +210,15 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_21_115930) do t.index ["weapon_key3_id"], name: "index_grid_weapons_on_weapon_key3_id" end + create_table "guidebooks", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.string "granblue_id", null: false + t.string "name_en", null: false + t.string "name_jp", null: false + t.string "description_en", null: false + t.string "description_jp", null: false + t.datetime "created_at", default: -> { "CURRENT_TIMESTAMP" }, null: false + end + create_table "job_accessories", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "job_id" t.string "name_en", null: false @@ -297,7 +329,13 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_21_115930) do t.string "edit_key" t.uuid "local_id" t.integer "ultimate_mastery" + t.uuid "guidebook3_id" + t.uuid "guidebook1_id" + t.uuid "guidebook2_id" t.index ["accessory_id"], name: "index_parties_on_accessory_id" + t.index ["guidebook1_id"], name: "index_parties_on_guidebook1_id" + t.index ["guidebook2_id"], name: "index_parties_on_guidebook2_id" + t.index ["guidebook3_id"], name: "index_parties_on_guidebook3_id" t.index ["job_id"], name: "index_parties_on_job_id" t.index ["skill0_id"], name: "index_parties_on_skill0_id" t.index ["skill1_id"], name: "index_parties_on_skill1_id" @@ -316,6 +354,20 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_21_115930) do t.string "slug" end + create_table "sparks", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.string "user_id", null: false + t.string "guild_ids", null: false, array: true + t.integer "crystals", default: 0 + t.integer "tickets", default: 0 + t.integer "ten_tickets", default: 0 + t.string "target_type" + t.bigint "target_id" + t.datetime "updated_at", default: -> { "CURRENT_TIMESTAMP" }, null: false + t.string "target_memo" + t.index ["target_type", "target_id"], name: "index_sparks_on_target" + t.index ["user_id"], name: "index_sparks_on_user_id", unique: true + end + create_table "summons", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.string "name_en" t.string "name_jp" @@ -398,7 +450,9 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_21_115930) do t.integer "awakening_types", default: [], array: true t.string "nicknames_en", default: [], null: false, array: true t.string "nicknames_jp", default: [], null: false, array: true + t.uuid "recruits_id" t.index ["name_en"], name: "index_weapons_on_name_en", opclass: :gin_trgm_ops, using: :gin + t.index ["recruits_id"], name: "index_weapons_on_recruits_id" end add_foreign_key "favorites", "parties" @@ -413,6 +467,9 @@ ActiveRecord::Schema[7.0].define(version: 2023_03_21_115930) do add_foreign_key "jobs", "jobs", column: "base_job_id" add_foreign_key "oauth_access_grants", "oauth_applications", column: "application_id" add_foreign_key "oauth_access_tokens", "oauth_applications", column: "application_id" + add_foreign_key "parties", "guidebooks", column: "guidebook1_id" + add_foreign_key "parties", "guidebooks", column: "guidebook2_id" + add_foreign_key "parties", "guidebooks", column: "guidebook3_id" add_foreign_key "parties", "job_accessories", column: "accessory_id" add_foreign_key "parties", "job_skills", column: "skill0_id" add_foreign_key "parties", "job_skills", column: "skill1_id" From 190b5b29ea1ebdc53c841fddf5c696688859669a Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 4 Jun 2023 22:57:32 -0700 Subject: [PATCH 05/12] Update download and export scripts --- lib/tasks/download_images.rake | 7 +++-- lib/tasks/export_job.rake | 54 +++++++++++++++++++++++++++++----- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/lib/tasks/download_images.rake b/lib/tasks/download_images.rake index ec61cb2..9079f89 100644 --- a/lib/tasks/download_images.rake +++ b/lib/tasks/download_images.rake @@ -106,7 +106,7 @@ namespace :granblue do puts "Summon #{id}" sizes.each do |size| - path = "#{Rails.root}/download/character-#{size}" + path = "#{Rails.root}/download/summon-#{size}" download_images(url[size.to_sym], size, path) end end @@ -125,7 +125,10 @@ namespace :granblue do elsif object == 'weapon' download_weapon_images(id) elsif object == 'summon' - download_summon_images(id) + download_summon_images("#{id}") + download_summon_images("#{id}_02") + download_summon_images("#{id}_03") + download_summon_images("#{id}_04") end end end diff --git a/lib/tasks/export_job.rake b/lib/tasks/export_job.rake index 87bdb4d..32f640d 100644 --- a/lib/tasks/export_job.rake +++ b/lib/tasks/export_job.rake @@ -1,33 +1,73 @@ namespace :granblue do namespace :export do def build_job_icon_url(id) - # Set up URL base_url = 'https://prd-game-a-granbluefantasy.akamaized.net/assets_en/img/sp/ui/icon/job' extension = '.png' "#{base_url}/#{id}#{extension}" end - desc 'Exports a list of weapon URLs for a given size' - task :job do |_t, _args| - # Include weapon model + def build_job_portrait_url(id, proficiency, gender) + base_url = 'https://prd-game-a1-granbluefantasy.akamaized.net/assets_en/img/sp/assets/leader/quest' + extension = '.jpg' + + prefix = "" + case proficiency + when 1 + prefix = "sw" + when 2 + prefix = "kn" + when 3 + prefix = "ax" + when 4 + prefix = "sp" + when 5 + prefix = "bw" + when 6 + prefix = "wa" + when 7 + prefix = "me" + when 8 + prefix = "mc" + when 9 + prefix = "gu" + when 10 + prefix = "kt" + end + + "#{base_url}/#{id}_#{prefix}_#{gender}_01#{extension}" + end + + # job-icon + def write_urls(size) + # Include model Dir.glob("#{Rails.root}/app/models/job.rb").each { |file| require file } # Set up filepath dir = "#{Rails.root}/export/" - filename = "#{dir}/job-icon.txt" + filename = "#{dir}job-#{size}.txt" FileUtils.mkdir(dir) unless Dir.exist?(dir) # Write to file File.open(filename, 'w') do |f| Job.all.each do |w| - f.write("#{build_job_icon_url(w.granblue_id.to_s)} \n") + if size == 'icon' + f.write("#{build_job_icon_url(w.granblue_id.to_s)} \n") + elsif size == 'portrait' + f.write("#{build_job_portrait_url(w.granblue_id.to_s, w.proficiency1, 0)} \n") + f.write("#{build_job_portrait_url(w.granblue_id.to_s, w.proficiency1, 1)} \n") + end end end # CLI output count = `wc -l #{filename}`.split.first.to_i - puts "Wrote #{count} job URLs for icon size" + puts "Wrote #{count} job URLs for #{size} size" + end + + desc 'Exports a list of job URLs for a given size' + task :job, [:size] => :environment do |_t, args| + write_urls(args[:size]) end end end From 56ccbe3dbbac8edb38202e6abf5cbb6c91b0379d Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 18 Jun 2023 02:07:57 -0700 Subject: [PATCH 06/12] Support for Siero, raids rework and edit party rework (#96) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add guidebooks migration * Implement business logic for reading Guidebooks * Change to individual guidebook columns * Properly output guidebook description * Move to 1-index guidebooks * Update party-related files for 1-index guidebooks * Add tables for Siero * Add raid groups table * Update raid model To belong to the RaidGroup class * Update job class To have many job skills * Add endpoint for raid groups * Update Raid blueprint with views * Added down for creating table * Add guidebooks flag and auto summon flag * Guidebooks → RaidGroup * Auto summon → Party * Add views to Raid blueprint * Add views and guidebook flag to RaidGroup blueprint * Add auto summon and Raid view to Party blueprint --- app/blueprints/api/v1/party_blueprint.rb | 6 ++-- app/blueprints/api/v1/raid_blueprint.rb | 19 +++++++---- app/blueprints/api/v1/raid_group_blueprint.rb | 23 +++++++++++++ app/controllers/api/v1/parties_controller.rb | 3 +- app/controllers/api/v1/raids_controller.rb | 6 +++- app/models/job.rb | 1 + app/models/raid.rb | 2 ++ app/models/raid_group.rb | 9 ++++++ config/routes.rb | 1 + .../20230529210259_add_raid_groups_table.rb | 16 ++++++++++ .../20230529215259_add_raid_group_to_raids.rb | 6 ++++ .../20230530000739_add_hl_to_raid_groups.rb | 5 +++ ...1115422_remove_group_integer_from_raids.rb | 5 +++ ...618051308_add_guidebooks_to_raid_groups.rb | 5 +++ ...230618051638_add_auto_summon_to_parties.rb | 5 +++ db/schema.rb | 32 +++++++++++++++++-- 16 files changed, 132 insertions(+), 12 deletions(-) create mode 100644 app/blueprints/api/v1/raid_group_blueprint.rb create mode 100644 app/models/raid_group.rb create mode 100644 db/migrate/20230529210259_add_raid_groups_table.rb create mode 100644 db/migrate/20230529215259_add_raid_group_to_raids.rb create mode 100644 db/migrate/20230530000739_add_hl_to_raid_groups.rb create mode 100644 db/migrate/20230531115422_remove_group_integer_from_raids.rb create mode 100644 db/migrate/20230618051308_add_guidebooks_to_raid_groups.rb create mode 100644 db/migrate/20230618051638_add_auto_summon_to_parties.rb diff --git a/app/blueprints/api/v1/party_blueprint.rb b/app/blueprints/api/v1/party_blueprint.rb index fe6674d..ef5ba48 100644 --- a/app/blueprints/api/v1/party_blueprint.rb +++ b/app/blueprints/api/v1/party_blueprint.rb @@ -34,7 +34,8 @@ module Api view :minimal do fields :name, :element, :shortcode, :favorited, :extra, - :full_auto, :clear_time, :auto_guard, :created_at, :updated_at + :full_auto, :clear_time, :auto_guard, :auto_summon, + :created_at, :updated_at field :remix do |p| p.is_remix @@ -49,7 +50,8 @@ module Api end association :raid, - blueprint: RaidBlueprint + blueprint: RaidBlueprint, + view: :full association :job, blueprint: JobBlueprint diff --git a/app/blueprints/api/v1/raid_blueprint.rb b/app/blueprints/api/v1/raid_blueprint.rb index 295c09a..be26e32 100644 --- a/app/blueprints/api/v1/raid_blueprint.rb +++ b/app/blueprints/api/v1/raid_blueprint.rb @@ -3,14 +3,21 @@ module Api module V1 class RaidBlueprint < ApiBlueprint - field :name do |raid| - { - en: raid.name_en, - ja: raid.name_jp - } + view :nested do + field :name do |raid| + { + en: raid.name_en, + ja: raid.name_jp + } + end + + fields :slug, :level, :element end - fields :slug, :level, :group, :element + view :full do + include_view :nested + association :group, blueprint: RaidGroupBlueprint, view: :flat + end end end end diff --git a/app/blueprints/api/v1/raid_group_blueprint.rb b/app/blueprints/api/v1/raid_group_blueprint.rb new file mode 100644 index 0000000..c65a0fa --- /dev/null +++ b/app/blueprints/api/v1/raid_group_blueprint.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Api + module V1 + class RaidGroupBlueprint < ApiBlueprint + view :flat do + field :name do |group| + { + en: group.name_en, + ja: group.name_jp + } + end + + fields :difficulty, :order, :section, :extra, :guidebooks, :hl + end + + view :full do + include_view :flat + association :raids, blueprint: RaidBlueprint, view: :full + end + end + end +end diff --git a/app/controllers/api/v1/parties_controller.rb b/app/controllers/api/v1/parties_controller.rb index 8bbd66a..8dec3bd 100644 --- a/app/controllers/api/v1/parties_controller.rb +++ b/app/controllers/api/v1/parties_controller.rb @@ -56,7 +56,7 @@ module Api # TODO: Validate accessory with job return render json: PartyBlueprint.render(@party, view: :full, root: :party) if @party.save - + render_validation_error_response(@party) end @@ -259,6 +259,7 @@ module Api :skill3_id, :full_auto, :auto_guard, + :auto_summon, :charge_attack, :clear_time, :button_count, diff --git a/app/controllers/api/v1/raids_controller.rb b/app/controllers/api/v1/raids_controller.rb index f5b898e..e59397f 100644 --- a/app/controllers/api/v1/raids_controller.rb +++ b/app/controllers/api/v1/raids_controller.rb @@ -4,7 +4,11 @@ module Api module V1 class RaidsController < Api::V1::ApiController def all - render json: RaidBlueprint.render(Raid.all) + render json: RaidBlueprint.render(Raid.all, view: :full) + end + + def groups + render json: RaidGroupBlueprint.render(RaidGroup.all, view: :full) end end end diff --git a/app/models/job.rb b/app/models/job.rb index beb0ce4..7cb8d6b 100644 --- a/app/models/job.rb +++ b/app/models/job.rb @@ -2,6 +2,7 @@ class Job < ApplicationRecord belongs_to :party + has_many :skills, class_name: 'JobSkill' belongs_to :base_job, foreign_key: 'base_job_id', diff --git a/app/models/raid.rb b/app/models/raid.rb index 9163f71..05a6934 100644 --- a/app/models/raid.rb +++ b/app/models/raid.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class Raid < ApplicationRecord + belongs_to :group, class_name: 'RaidGroup', foreign_key: :group_id + def blueprint RaidBlueprint end diff --git a/app/models/raid_group.rb b/app/models/raid_group.rb new file mode 100644 index 0000000..3c1010b --- /dev/null +++ b/app/models/raid_group.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class RaidGroup < ApplicationRecord + has_many :raids, class_name: 'Raid', foreign_key: :group_id + + def blueprint + RaidGroupBlueprint + end +end diff --git a/config/routes.rb b/config/routes.rb index 9218e0f..00f0e26 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -45,6 +45,7 @@ Rails.application.routes.draw do get 'guidebooks', to: 'guidebooks#all' get 'raids', to: 'raids#all' + get 'raids/groups', to: 'raids#groups' get 'weapon_keys', to: 'weapon_keys#all' post 'characters', to: 'grid_characters#create' diff --git a/db/migrate/20230529210259_add_raid_groups_table.rb b/db/migrate/20230529210259_add_raid_groups_table.rb new file mode 100644 index 0000000..7803d82 --- /dev/null +++ b/db/migrate/20230529210259_add_raid_groups_table.rb @@ -0,0 +1,16 @@ +class AddRaidGroupsTable < ActiveRecord::Migration[7.0] + def up + create_table :raid_groups, id: :uuid, default: -> { "gen_random_uuid()" } do |t| + t.string :name_en, null: false + t.string :name_jp, null: false + t.integer :difficulty + t.integer :order, null: false + t.integer :section, default: 1, null: false + t.boolean :extra, default: false, null: false + end + end + + def down + drop_table :raid_groups + end +end diff --git a/db/migrate/20230529215259_add_raid_group_to_raids.rb b/db/migrate/20230529215259_add_raid_group_to_raids.rb new file mode 100644 index 0000000..e708a20 --- /dev/null +++ b/db/migrate/20230529215259_add_raid_group_to_raids.rb @@ -0,0 +1,6 @@ +class AddRaidGroupToRaids < ActiveRecord::Migration[7.0] + def change + add_reference :raids, :group, null: true, to_table: 'raid_groups', type: :uuid + add_foreign_key :raids, :raid_groups, column: :group_id + end +end diff --git a/db/migrate/20230530000739_add_hl_to_raid_groups.rb b/db/migrate/20230530000739_add_hl_to_raid_groups.rb new file mode 100644 index 0000000..c302776 --- /dev/null +++ b/db/migrate/20230530000739_add_hl_to_raid_groups.rb @@ -0,0 +1,5 @@ +class AddHlToRaidGroups < ActiveRecord::Migration[7.0] + def change + add_column :raid_groups, :hl, :boolean, default: true, null: false + end +end diff --git a/db/migrate/20230531115422_remove_group_integer_from_raids.rb b/db/migrate/20230531115422_remove_group_integer_from_raids.rb new file mode 100644 index 0000000..e315719 --- /dev/null +++ b/db/migrate/20230531115422_remove_group_integer_from_raids.rb @@ -0,0 +1,5 @@ +class RemoveGroupIntegerFromRaids < ActiveRecord::Migration[7.0] + def change + remove_column :raids, :group, :integer + end +end diff --git a/db/migrate/20230618051308_add_guidebooks_to_raid_groups.rb b/db/migrate/20230618051308_add_guidebooks_to_raid_groups.rb new file mode 100644 index 0000000..1120a47 --- /dev/null +++ b/db/migrate/20230618051308_add_guidebooks_to_raid_groups.rb @@ -0,0 +1,5 @@ +class AddGuidebooksToRaidGroups < ActiveRecord::Migration[7.0] + def change + add_column :raid_groups, :guidebooks, :boolean, default: false, null: false + end +end diff --git a/db/migrate/20230618051638_add_auto_summon_to_parties.rb b/db/migrate/20230618051638_add_auto_summon_to_parties.rb new file mode 100644 index 0000000..ba91a4b --- /dev/null +++ b/db/migrate/20230618051638_add_auto_summon_to_parties.rb @@ -0,0 +1,5 @@ +class AddAutoSummonToParties < ActiveRecord::Migration[7.0] + def change + add_column :parties, :auto_summon, :boolean, default: false, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index ad74e64..c54e829 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[7.0].define(version: 2023_05_03_224353) do +ActiveRecord::Schema[7.0].define(version: 2023_06_18_051638) do # These are extensions that must be enabled in order to support this database enable_extension "btree_gin" enable_extension "pg_trgm" @@ -332,6 +332,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_05_03_224353) do t.uuid "guidebook3_id" t.uuid "guidebook1_id" t.uuid "guidebook2_id" + t.boolean "auto_summon", default: false, null: false t.index ["accessory_id"], name: "index_parties_on_accessory_id" t.index ["guidebook1_id"], name: "index_parties_on_guidebook1_id" t.index ["guidebook2_id"], name: "index_parties_on_guidebook2_id" @@ -345,13 +346,39 @@ ActiveRecord::Schema[7.0].define(version: 2023_05_03_224353) do t.index ["user_id"], name: "index_parties_on_user_id" end + create_table "raid_groups", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.string "name_en", null: false + t.string "name_jp", null: false + t.integer "difficulty" + t.integer "order", null: false + t.integer "section", default: 1, null: false + t.boolean "extra", default: false, null: false + t.boolean "hl", default: true, null: false + t.boolean "guidebooks", default: false, null: false + end + create_table "raids", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.string "name_en" t.string "name_jp" t.integer "level" - t.integer "group" t.integer "element" t.string "slug" + t.uuid "group_id" + t.index ["group_id"], name: "index_raids_on_group_id" + end + + create_table "sparks", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.string "user_id", null: false + t.string "guild_ids", null: false, array: true + t.integer "crystals", default: 0 + t.integer "tickets", default: 0 + t.integer "ten_tickets", default: 0 + t.string "target_type" + t.bigint "target_id" + t.datetime "updated_at", default: -> { "CURRENT_TIMESTAMP" }, null: false + t.string "target_memo" + t.index ["target_type", "target_id"], name: "index_sparks_on_target" + t.index ["user_id"], name: "index_sparks_on_user_id", unique: true end create_table "sparks", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| @@ -479,4 +506,5 @@ ActiveRecord::Schema[7.0].define(version: 2023_05_03_224353) do add_foreign_key "parties", "parties", column: "source_party_id" add_foreign_key "parties", "raids" add_foreign_key "parties", "users" + add_foreign_key "raids", "raid_groups", column: "group_id" end From a47d827e0860e59665b518853eec93f0c78b449b Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 18 Jun 2023 05:19:30 -0700 Subject: [PATCH 07/12] Add quick summons (#97) * Adds quick summon migration * Add route to update quick summon * Add logic to update quick summon --- .../api/v1/grid_summon_blueprint.rb | 2 +- .../api/v1/grid_summons_controller.rb | 50 ++++++++++++------- config/routes.rb | 1 + ...112807_add_quick_summon_to_grid_summons.rb | 5 ++ 4 files changed, 38 insertions(+), 20 deletions(-) create mode 100644 db/migrate/20230315112807_add_quick_summon_to_grid_summons.rb diff --git a/app/blueprints/api/v1/grid_summon_blueprint.rb b/app/blueprints/api/v1/grid_summon_blueprint.rb index 116b7ab..f866602 100644 --- a/app/blueprints/api/v1/grid_summon_blueprint.rb +++ b/app/blueprints/api/v1/grid_summon_blueprint.rb @@ -9,7 +9,7 @@ module Api end view :nested do - fields :main, :friend, :position, :uncap_level, :transcendence_step + fields :main, :friend, :position, :quick_summon, :uncap_level, :transcendence_step association :summon, name: :object, blueprint: SummonBlueprint end diff --git a/app/controllers/api/v1/grid_summons_controller.rb b/app/controllers/api/v1/grid_summons_controller.rb index 132a016..c4618a1 100644 --- a/app/controllers/api/v1/grid_summons_controller.rb +++ b/app/controllers/api/v1/grid_summons_controller.rb @@ -4,11 +4,11 @@ module Api module V1 class GridSummonsController < Api::V1::ApiController attr_reader :party, :incoming_summon - - before_action :set, only: %w[update destroy] + + before_action :set, only: %w[update update_uncap_level update_quick_summon destroy] before_action :find_party, only: :create before_action :find_incoming_summon, only: :create - before_action :authorize, only: %i[create update destroy] + before_action :authorize, only: %i[create update update_uncap_level update_quick_summon destroy] def create # Create the GridSummon with the desired parameters @@ -30,6 +30,31 @@ module Api render_validation_error_response(@character) end + def update_uncap_level + @summon.uncap_level = summon_params[:uncap_level] + @summon.transcendence_step = 0 + + return unless @summon.save! + + render json: GridSummonBlueprint.render(@summon, view: :nested, root: :grid_summon) + end + + def update_quick_summon + quick_summons = @summon.party.summons.select(&:quick_summon) + + quick_summons.each do |summon| + summon.update!(quick_summon: false) + end + + @summon.update!(quick_summon: summon_params[:quick_summon]) + return unless @summon.persisted? + + quick_summons -= [@summon] + summons = [@summon] + quick_summons + + render json: GridSummonBlueprint.render(summons, view: :nested, root: :summons) + end + def save_summon(summon) if (grid_summon = GridSummon.where( party_id: party.id, @@ -58,19 +83,6 @@ module Api render json: output end - def update_uncap_level - summon = GridSummon.find(summon_params[:id]) - - render_unauthorized_response if current_user && (summon.party.user != current_user) - - summon.uncap_level = summon_params[:uncap_level] - summon.transcendence_step = 0 - - return unless summon.save! - - render json: GridSummonBlueprint.render(summon, view: :nested, root: :grid_summon) - end - def destroy render_unauthorized_response if @summon.party.user != current_user return render json: GridSummonBlueprint.render(@summon, view: :destroyed) if @summon.destroy @@ -103,13 +115,13 @@ module Api end def set - @summon = GridSummon.where('id = ?', params[:id]).first + @summon = GridSummon.where('id = ?', summon_params[:id]).first end # Specify whitelisted properties that can be modified. def summon_params - params.require(:summon).permit(:id, :party_id, :summon_id, :position, :main, :friend, :uncap_level, - :transcendence_step) + params.require(:summon).permit(:id, :party_id, :summon_id, :position, :main, :friend, + :quick_summon, :uncap_level, :transcendence_step) end end end diff --git a/config/routes.rb b/config/routes.rb index 00f0e26..eedb079 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -60,6 +60,7 @@ Rails.application.routes.draw do post 'summons', to: 'grid_summons#create' post 'summons/update_uncap', to: 'grid_summons#update_uncap_level' + post 'summons/update_quick_summon', to: 'grid_summons#update_quick_summon' delete 'summons', to: 'grid_summons#destroy' delete 'favorites', to: 'favorites#destroy' diff --git a/db/migrate/20230315112807_add_quick_summon_to_grid_summons.rb b/db/migrate/20230315112807_add_quick_summon_to_grid_summons.rb new file mode 100644 index 0000000..a50b5f0 --- /dev/null +++ b/db/migrate/20230315112807_add_quick_summon_to_grid_summons.rb @@ -0,0 +1,5 @@ +class AddQuickSummonToGridSummons < ActiveRecord::Migration[7.0] + def change + add_column :grid_summons, :quick_summon, :boolean, default: false, null: false + end +end From 483eec0636a94624f20122e9a238c08465445bae Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 18 Jun 2023 05:23:07 -0700 Subject: [PATCH 08/12] Remove ap call --- app/controllers/api/v1/grid_summons_controller.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/controllers/api/v1/grid_summons_controller.rb b/app/controllers/api/v1/grid_summons_controller.rb index 132a016..b64fddd 100644 --- a/app/controllers/api/v1/grid_summons_controller.rb +++ b/app/controllers/api/v1/grid_summons_controller.rb @@ -46,7 +46,6 @@ module Api def handle_conflict(summon) conflict_summon = summon.conflicts(party) - ap conflict_summon return unless conflict_summon.summon.id == incoming_summon.id old_position = conflict_summon.position From 57955ba0a9a8ee058e9a40aca6e106550eb6ac70 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 18 Jun 2023 06:22:47 -0700 Subject: [PATCH 09/12] Add logic to updating summon uncap You couldn't actually update summon transcendence on staging, maybe due to a bug? Now you can. And it won't let you update outside of the bounds of what is defined on the canonical object. --- .../api/v1/grid_summons_controller.rb | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/v1/grid_summons_controller.rb b/app/controllers/api/v1/grid_summons_controller.rb index 9eed9cb..67d9b4d 100644 --- a/app/controllers/api/v1/grid_summons_controller.rb +++ b/app/controllers/api/v1/grid_summons_controller.rb @@ -31,10 +31,32 @@ module Api end def update_uncap_level - @summon.uncap_level = summon_params[:uncap_level] - @summon.transcendence_step = 0 + summon = @summon.summon + max_uncap_level = if summon.flb + 4 + elsif summon.ulb + 5 + else + 3 + end - return unless @summon.save! + greater_than_max_uncap = summon_params[:uncap_level].to_i > max_uncap_level + can_be_transcended = summon.xlb && summon_params[:transcendence_step] && summon_params[:transcendence_step]&.to_i.positive? + + uncap_level = if greater_than_max_uncap || can_be_transcended + max_uncap_level + else + summon_params[:uncap_level] + end + + transcendence_step = summon.xlb ? summon_params[:transcendence_step] : 0 + + @summon.update!( + uncap_level: uncap_level, + transcendence_step: transcendence_step || 0 + ) + + return unless @summon.persisted? render json: GridSummonBlueprint.render(@summon, view: :nested, root: :grid_summon) end @@ -114,6 +136,7 @@ module Api end def set + ap summon_params @summon = GridSummon.where('id = ?', summon_params[:id]).first end From 66eaece635443fcc5f88eefbbf83aaca93776d1e Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 18 Jun 2023 15:44:49 -0700 Subject: [PATCH 10/12] Fix summon logic Updated logic for updating summon uncap and transcendence levels and quick summon status. --- .../api/v1/grid_summons_controller.rb | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/v1/grid_summons_controller.rb b/app/controllers/api/v1/grid_summons_controller.rb index 67d9b4d..f55101c 100644 --- a/app/controllers/api/v1/grid_summons_controller.rb +++ b/app/controllers/api/v1/grid_summons_controller.rb @@ -32,7 +32,7 @@ module Api def update_uncap_level summon = @summon.summon - max_uncap_level = if summon.flb + max_uncap_level = if summon.flb && !summon.ulb 4 elsif summon.ulb 5 @@ -49,11 +49,15 @@ module Api summon_params[:uncap_level] end - transcendence_step = summon.xlb ? summon_params[:transcendence_step] : 0 + transcendence_step = if summon.xlb && summon_params[:transcendence_step] + summon_params[:transcendence_step] + else + 0 + end @summon.update!( uncap_level: uncap_level, - transcendence_step: transcendence_step || 0 + transcendence_step: transcendence_step ) return unless @summon.persisted? @@ -62,6 +66,8 @@ module Api end def update_quick_summon + return if [4, 5, 6].include?(@summon.position) + quick_summons = @summon.party.summons.select(&:quick_summon) quick_summons.each do |summon| @@ -136,8 +142,8 @@ module Api end def set - ap summon_params - @summon = GridSummon.where('id = ?', summon_params[:id]).first + id = summon_params[:id] ? summon_params[:id] : params[:id] + @summon = GridSummon.where('id = ?', id).first end # Specify whitelisted properties that can be modified. From 4567766530c665ca0598d9e6b1dd314d59f80bd5 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 18 Jun 2023 23:43:50 -0700 Subject: [PATCH 11/12] Fix searching in Japanese (#99) This was broken because we were using the browser-provided locale as a prefix to our method, but that is 'ja' and our methods were prefixed with 'jp'. --- app/models/character.rb | 2 +- app/models/guidebook.rb | 2 +- app/models/job_skill.rb | 2 +- app/models/summon.rb | 2 +- app/models/weapon.rb | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/models/character.rb b/app/models/character.rb index c772471..6bb30a6 100644 --- a/app/models/character.rb +++ b/app/models/character.rb @@ -11,7 +11,7 @@ class Character < ApplicationRecord } } - pg_search_scope :jp_search, + pg_search_scope :ja_search, against: :name_jp, using: { tsearch: { diff --git a/app/models/guidebook.rb b/app/models/guidebook.rb index 581068a..c46c431 100644 --- a/app/models/guidebook.rb +++ b/app/models/guidebook.rb @@ -14,7 +14,7 @@ class Guidebook < ApplicationRecord } } - pg_search_scope :jp_search, + pg_search_scope :ja_search, against: :name_jp, using: { tsearch: { diff --git a/app/models/job_skill.rb b/app/models/job_skill.rb index 9e0bcd3..d2b6b83 100644 --- a/app/models/job_skill.rb +++ b/app/models/job_skill.rb @@ -16,7 +16,7 @@ class JobSkill < ApplicationRecord } } - pg_search_scope :jp_search, + pg_search_scope :ja_search, against: :name_jp, using: { tsearch: { diff --git a/app/models/summon.rb b/app/models/summon.rb index 7efab1b..cd9245a 100644 --- a/app/models/summon.rb +++ b/app/models/summon.rb @@ -11,7 +11,7 @@ class Summon < ApplicationRecord } } - pg_search_scope :jp_search, + pg_search_scope :ja_search, against: :name_jp, using: { tsearch: { diff --git a/app/models/weapon.rb b/app/models/weapon.rb index c18a313..bbb4c7d 100644 --- a/app/models/weapon.rb +++ b/app/models/weapon.rb @@ -11,7 +11,7 @@ class Weapon < ApplicationRecord } } - pg_search_scope :jp_search, + pg_search_scope :ja_search, against: :name_jp, using: { tsearch: { From dfbfada0d0952624cb99a94ba3fb767b7ec016b9 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Mon, 19 Jun 2023 00:21:53 -0700 Subject: [PATCH 12/12] Fix display of base skills (#100) Base skills were not displaying due to a missing case in our search code. This is now fixed. --- app/controllers/api/v1/search_controller.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb index 0d94ae0..b60c3d0 100644 --- a/app/controllers/api/v1/search_controller.rb +++ b/app/controllers/api/v1/search_controller.rb @@ -158,6 +158,13 @@ module Api .where(job: { base_job: job.base_job.id }, emp: true) .where.not(job: job.id) ) + .or( + JobSkill.joins(:job) + .method("#{locale}_search").call(search_params[:query]) + .where(conditions) + .where(job: { base_job: job.base_job.id }, base: true) + .where.not(job: job.id) + ) else JobSkill.all .joins(:job)