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
This commit is contained in:
Justin Edmund 2023-06-04 22:23:34 -07:00 committed by GitHub
parent 037f74d86d
commit af8b1aa9c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 295 additions and 4 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

37
app/models/guidebook.rb Normal file
View file

@ -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

View file

@ -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

View file

@ -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'

View file

@ -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

View file

@ -0,0 +1,5 @@
class AddGuidebooksToParty < ActiveRecord::Migration[7.0]
def change
add_column :parties, :guidebooks, :uuid, array: true, default: [], null: false
end
end

View file

@ -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

View file

@ -0,0 +1,5 @@
class RenameGuidebooksToGuidebookIDs < ActiveRecord::Migration[7.0]
def change
rename_column :parties, :guidebooks, :guidebook_ids
end
end

View file

@ -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

View file

@ -0,0 +1,5 @@
class RenameGuidebookColumns < ActiveRecord::Migration[7.0]
def change
rename_column :parties, :guidebook0_id, :guidebook3_id
end
end

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,5 @@
class MakeGachaDrawableIdUnique < ActiveRecord::Migration[7.0]
def change
add_index :gacha, :drawable_id, unique: true
end
end

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,5 @@
class AddTargetMemoToSparks < ActiveRecord::Migration[7.0]
def change
add_column :sparks, :target_memo, :string
end
end

View file

@ -0,0 +1,5 @@
class MakeUserIdUniqueInSparks < ActiveRecord::Migration[7.0]
def change
add_index :sparks, :user_id, unique: true
end
end

View file

@ -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"