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:
parent
037f74d86d
commit
af8b1aa9c1
23 changed files with 295 additions and 4 deletions
23
app/blueprints/api/v1/guidebook_blueprint.rb
Normal file
23
app/blueprints/api/v1/guidebook_blueprint.rb
Normal 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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
11
app/controllers/api/v1/guidebooks_controller.rb
Normal file
11
app/controllers/api/v1/guidebooks_controller.rb
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
37
app/models/guidebook.rb
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
12
db/migrate/20230418052314_add_guidebooks.rb
Normal file
12
db/migrate/20230418052314_add_guidebooks.rb
Normal 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
|
||||
5
db/migrate/20230418052325_add_guidebooks_to_party.rb
Normal file
5
db/migrate/20230418052325_add_guidebooks_to_party.rb
Normal 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
|
||||
6
db/migrate/20230418061932_update_guidebooks_structure.rb
Normal file
6
db/migrate/20230418061932_update_guidebooks_structure.rb
Normal 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
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
class RenameGuidebooksToGuidebookIDs < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
rename_column :parties, :guidebooks, :guidebook_ids
|
||||
end
|
||||
end
|
||||
8
db/migrate/20230419033648_split_guidebooks_on_party.rb
Normal file
8
db/migrate/20230419033648_split_guidebooks_on_party.rb
Normal 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
|
||||
5
db/migrate/20230419102354_rename_guidebook_columns.rb
Normal file
5
db/migrate/20230419102354_rename_guidebook_columns.rb
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
class RenameGuidebookColumns < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
rename_column :parties, :guidebook0_id, :guidebook3_id
|
||||
end
|
||||
end
|
||||
13
db/migrate/20230423070004_add_gacha_table.rb
Normal file
13
db/migrate/20230423070004_add_gacha_table.rb
Normal 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
|
||||
5
db/migrate/20230423071446_add_recruits_to_weapon.rb
Normal file
5
db/migrate/20230423071446_add_recruits_to_weapon.rb
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
class MakeGachaDrawableIdUnique < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
add_index :gacha, :drawable_id, unique: true
|
||||
end
|
||||
end
|
||||
8
db/migrate/20230502012823_add_gacha_rateups_table.rb
Normal file
8
db/migrate/20230502012823_add_gacha_rateups_table.rb
Normal 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
|
||||
11
db/migrate/20230503221903_add_sparks_table.rb
Normal file
11
db/migrate/20230503221903_add_sparks_table.rb
Normal 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
|
||||
5
db/migrate/20230503224345_add_target_memo_to_sparks.rb
Normal file
5
db/migrate/20230503224345_add_target_memo_to_sparks.rb
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
class AddTargetMemoToSparks < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
add_column :sparks, :target_memo, :string
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
class MakeUserIdUniqueInSparks < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
add_index :sparks, :user_id, unique: true
|
||||
end
|
||||
end
|
||||
59
db/schema.rb
59
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"
|
||||
|
|
|
|||
Loading…
Reference in a new issue