Merge branch 'main' into awakening
This commit is contained in:
commit
7bdee95c0e
109 changed files with 1959 additions and 1784 deletions
46
Gemfile
46
Gemfile
|
|
@ -1,10 +1,10 @@
|
|||
source 'https://rubygems.org'
|
||||
ruby '3.0.0'
|
||||
|
||||
gem 'rails'
|
||||
gem 'pg'
|
||||
gem 'bootsnap'
|
||||
gem 'pg'
|
||||
gem 'rack-cors'
|
||||
gem 'rails'
|
||||
|
||||
# A Ruby Web Server Built For Concurrency
|
||||
gem 'puma'
|
||||
|
|
@ -16,8 +16,8 @@ gem 'bcrypt'
|
|||
# Doorkeeper is an OAuth 2 provider for Rails and Grape.
|
||||
gem 'doorkeeper'
|
||||
|
||||
# Templating system with JSON, XML and Plist support.
|
||||
gem 'rabl'
|
||||
# Simple, Fast, and Declarative Serialization Library for Ruby
|
||||
gem 'blueprinter'
|
||||
|
||||
# Optimized JSON.
|
||||
gem 'oj'
|
||||
|
|
@ -35,7 +35,7 @@ gem 'gemoji-parser'
|
|||
gem 'awesome_nested_set'
|
||||
|
||||
# An email validator for Rails
|
||||
gem "email_validator"
|
||||
gem 'email_validator'
|
||||
|
||||
# pg_search builds ActiveRecord named scopes that take advantage of PostgreSQL’s full text search
|
||||
gem 'pg_search'
|
||||
|
|
@ -44,31 +44,31 @@ gem 'pg_search'
|
|||
gem 'will_paginate', '~> 3.3'
|
||||
|
||||
group :doc do
|
||||
gem 'sdoc'
|
||||
gem 'apipie-rails'
|
||||
gem 'apipie-rails'
|
||||
gem 'sdoc'
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
gem 'awesome_print'
|
||||
gem 'dotenv-rails'
|
||||
gem 'factory_bot_rails'
|
||||
gem 'faker'
|
||||
gem 'rspec-rails'
|
||||
gem 'rspec_junit_formatter'
|
||||
gem 'awesome_print'
|
||||
gem 'dotenv-rails'
|
||||
gem 'factory_bot_rails'
|
||||
gem 'faker'
|
||||
gem 'rspec_junit_formatter'
|
||||
gem 'rspec-rails'
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem 'listen'
|
||||
gem 'rubocop'
|
||||
gem 'solargraph'
|
||||
gem 'spring-commands-rspec'
|
||||
gem 'spring'
|
||||
gem 'listen'
|
||||
gem 'rubocop'
|
||||
gem 'solargraph'
|
||||
gem 'spring'
|
||||
gem 'spring-commands-rspec'
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'api_matchers'
|
||||
gem 'byebug'
|
||||
gem 'database_cleaner'
|
||||
gem 'shoulda-matchers'
|
||||
gem 'simplecov', :require => false
|
||||
gem 'api_matchers'
|
||||
gem 'byebug'
|
||||
gem 'database_cleaner'
|
||||
gem 'shoulda-matchers'
|
||||
gem 'simplecov', require: false
|
||||
end
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ GEM
|
|||
backport (1.2.0)
|
||||
bcrypt (3.1.16)
|
||||
benchmark (0.2.0)
|
||||
blueprinter (0.25.3)
|
||||
bootsnap (1.9.1)
|
||||
msgpack (~> 1.0)
|
||||
builder (3.2.4)
|
||||
|
|
@ -147,8 +148,6 @@ GEM
|
|||
activesupport (>= 5.2)
|
||||
puma (5.5.2)
|
||||
nio4r (~> 2.0)
|
||||
rabl (0.14.5)
|
||||
activesupport (>= 2.3.14)
|
||||
racc (1.6.0)
|
||||
rack (2.2.3)
|
||||
rack-cors (1.1.1)
|
||||
|
|
@ -286,6 +285,7 @@ DEPENDENCIES
|
|||
awesome_nested_set
|
||||
awesome_print
|
||||
bcrypt
|
||||
blueprinter
|
||||
bootsnap
|
||||
byebug
|
||||
database_cleaner
|
||||
|
|
@ -301,7 +301,6 @@ DEPENDENCIES
|
|||
pg
|
||||
pg_search
|
||||
puma
|
||||
rabl
|
||||
rack-cors
|
||||
rails
|
||||
responders
|
||||
|
|
|
|||
12
app/blueprints/api/v1/api_blueprint.rb
Normal file
12
app/blueprints/api/v1/api_blueprint.rb
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class ApiBlueprint < Blueprinter::Base
|
||||
identifier :id
|
||||
|
||||
cattr_accessor :current_user
|
||||
cattr_writer :current_user
|
||||
end
|
||||
end
|
||||
end
|
||||
68
app/blueprints/api/v1/character_blueprint.rb
Normal file
68
app/blueprints/api/v1/character_blueprint.rb
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class CharacterBlueprint < ApiBlueprint
|
||||
field :name do |w|
|
||||
{
|
||||
en: w.name_en,
|
||||
ja: w.name_jp
|
||||
}
|
||||
end
|
||||
|
||||
fields :granblue_id, :character_id, :rarity,
|
||||
:element, :gender, :special
|
||||
|
||||
field :uncap do |w|
|
||||
{
|
||||
flb: w.flb,
|
||||
ulb: w.ulb
|
||||
}
|
||||
end
|
||||
|
||||
field :hp do |w|
|
||||
{
|
||||
min_hp: w.min_hp,
|
||||
max_hp: w.max_hp,
|
||||
max_hp_flb: w.max_hp_flb
|
||||
}
|
||||
end
|
||||
|
||||
field :atk do |w|
|
||||
{
|
||||
min_atk: w.min_atk,
|
||||
max_atk: w.max_atk,
|
||||
max_atk_flb: w.max_atk_flb
|
||||
}
|
||||
end
|
||||
|
||||
field :race do |w|
|
||||
[
|
||||
w.race1,
|
||||
w.race2
|
||||
]
|
||||
end
|
||||
|
||||
field :proficiency do |w|
|
||||
[
|
||||
w.proficiency1,
|
||||
w.proficiency2
|
||||
]
|
||||
end
|
||||
|
||||
field :data do |w|
|
||||
{
|
||||
base_da: w.base_da,
|
||||
base_ta: w.base_ta
|
||||
}
|
||||
end
|
||||
|
||||
field :ougi_ratio do |w|
|
||||
{
|
||||
ougi_ratio: w.ougi_ratio,
|
||||
ougi_ratio_flb: w.ougi_ratio_flb
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
31
app/blueprints/api/v1/conflict_blueprint.rb
Normal file
31
app/blueprints/api/v1/conflict_blueprint.rb
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class ConflictBlueprint < Blueprinter::Base
|
||||
field :position, if: ->(_fn, _obj, options) { options.key?(:incoming_position) } do |_, options|
|
||||
options[:incoming_position]
|
||||
end
|
||||
|
||||
view :characters do
|
||||
field :conflicts, if: ->(_fn, _obj, options) { options.key?(:conflict_characters) } do |_, options|
|
||||
GridCharacterBlueprint.render_as_hash(options[:conflict_characters], view: :nested)
|
||||
end
|
||||
|
||||
field :incoming, if: ->(_fn, _obj, options) { options.key?(:incoming_character) } do |_, options|
|
||||
CharacterBlueprint.render_as_hash(options[:incoming_character])
|
||||
end
|
||||
end
|
||||
|
||||
view :weapons do
|
||||
field :conflicts, if: ->(_fn, _obj, options) { options.key?(:conflict_weapons) } do |_, options|
|
||||
GridWeaponBlueprint.render_as_hash(options[:conflict_weapons], view: :nested)
|
||||
end
|
||||
|
||||
field :incoming, if: ->(_fn, _obj, options) { options.key?(:incoming_weapon) } do |_, options|
|
||||
WeaponBlueprint.render_as_hash(options[:incoming_weapon])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
15
app/blueprints/api/v1/empty_blueprint.rb
Normal file
15
app/blueprints/api/v1/empty_blueprint.rb
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class EmptyBlueprint < Blueprinter::Base
|
||||
field :available, if: ->(_field_name, _empty, options) { options.key?(:availability) } do |_, options|
|
||||
if options.key?(:email)
|
||||
User.where('email = ?', options[:email]).count.zero?
|
||||
elsif options.key?(:username)
|
||||
User.where('username = ?', options[:username]).count.zero?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
19
app/blueprints/api/v1/error_blueprint.rb
Normal file
19
app/blueprints/api/v1/error_blueprint.rb
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class ErrorBlueprint < Blueprinter::Base
|
||||
field :error, if: ->(_field_name, _error, options) { options.key?(:error) } do |_, options|
|
||||
options[:error]
|
||||
end
|
||||
|
||||
field :errors, if: ->(_field_name, _error, options) { options.key?(:errors) } do |_, options|
|
||||
options[:errors]
|
||||
end
|
||||
|
||||
field :errors, if: ->(_field_name, _error, options) { options.key?(:exception) } do |_, options|
|
||||
options[:exception]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
25
app/blueprints/api/v1/favorite_blueprint.rb
Normal file
25
app/blueprints/api/v1/favorite_blueprint.rb
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class FavoriteBlueprint < ApiBlueprint
|
||||
association :user,
|
||||
name: :user,
|
||||
blueprint: UserBlueprint,
|
||||
view: :minimal
|
||||
|
||||
association :party,
|
||||
name: :party,
|
||||
blueprint: PartyBlueprint,
|
||||
view: :preview
|
||||
|
||||
fields :created_at, :updated_at
|
||||
|
||||
view :destroyed do
|
||||
field :destroyed do
|
||||
true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
22
app/blueprints/api/v1/grid_character_blueprint.rb
Normal file
22
app/blueprints/api/v1/grid_character_blueprint.rb
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class GridCharacterBlueprint < ApiBlueprint
|
||||
view :uncap do
|
||||
association :party, blueprint: PartyBlueprint, view: :minimal
|
||||
fields :position, :uncap_level
|
||||
end
|
||||
|
||||
view :nested do
|
||||
fields :position, :uncap_level, :perpetuity
|
||||
association :character, name: :object, blueprint: CharacterBlueprint
|
||||
end
|
||||
|
||||
view :full do
|
||||
include_view :nested
|
||||
association :party, blueprint: PartyBlueprint, view: :minimal
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
22
app/blueprints/api/v1/grid_summon_blueprint.rb
Normal file
22
app/blueprints/api/v1/grid_summon_blueprint.rb
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class GridSummonBlueprint < ApiBlueprint
|
||||
view :uncap do
|
||||
association :party, blueprint: PartyBlueprint, view: :minimal
|
||||
fields :position, :uncap_level
|
||||
end
|
||||
|
||||
view :nested do
|
||||
fields :main, :friend, :position, :uncap_level
|
||||
association :summon, name: :object, blueprint: SummonBlueprint
|
||||
end
|
||||
|
||||
view :full do
|
||||
include_view :nested
|
||||
association :party, blueprint: PartyBlueprint, view: :minimal
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
41
app/blueprints/api/v1/grid_weapon_blueprint.rb
Normal file
41
app/blueprints/api/v1/grid_weapon_blueprint.rb
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class GridWeaponBlueprint < ApiBlueprint
|
||||
view :uncap do
|
||||
association :party, blueprint: PartyBlueprint, view: :minimal
|
||||
fields :position, :uncap_level
|
||||
end
|
||||
|
||||
view :nested do
|
||||
fields :mainhand, :position, :uncap_level, :element
|
||||
association :weapon, name: :object, blueprint: WeaponBlueprint
|
||||
|
||||
association :weapon_keys,
|
||||
blueprint: WeaponKeyBlueprint,
|
||||
if: lambda { |_field_name, w, _options|
|
||||
[2, 3, 17, 22].include?(w.weapon.series)
|
||||
}
|
||||
|
||||
field :ax, if: ->(_field_name, w, _options) { w.weapon.ax.positive? } do |w|
|
||||
[
|
||||
{
|
||||
modifier: w.ax_modifier1,
|
||||
strength: w.ax_strength1
|
||||
},
|
||||
{
|
||||
modifier: w.ax_modifier2,
|
||||
strength: w.ax_strength2
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
view :full do
|
||||
include_view :nested
|
||||
association :party, blueprint: PartyBlueprint, view: :minimal
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
23
app/blueprints/api/v1/job_blueprint.rb
Normal file
23
app/blueprints/api/v1/job_blueprint.rb
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class JobBlueprint < ApiBlueprint
|
||||
field :name do |job|
|
||||
{
|
||||
en: job.name_en,
|
||||
ja: job.name_jp
|
||||
}
|
||||
end
|
||||
|
||||
field :proficiency do |job|
|
||||
[
|
||||
job.proficiency1,
|
||||
job.proficiency2
|
||||
]
|
||||
end
|
||||
|
||||
fields :row, :ml, :order
|
||||
end
|
||||
end
|
||||
end
|
||||
20
app/blueprints/api/v1/job_skill_blueprint.rb
Normal file
20
app/blueprints/api/v1/job_skill_blueprint.rb
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class JobSkillBlueprint < ApiBlueprint
|
||||
field :name do |skill|
|
||||
{
|
||||
en: skill.name_en,
|
||||
ja: skill.name_jp
|
||||
}
|
||||
end
|
||||
|
||||
association :job,
|
||||
name: :job,
|
||||
blueprint: JobBlueprint
|
||||
|
||||
fields :slug, :color, :main, :base, :sub, :emp, :order
|
||||
end
|
||||
end
|
||||
end
|
||||
78
app/blueprints/api/v1/party_blueprint.rb
Normal file
78
app/blueprints/api/v1/party_blueprint.rb
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class PartyBlueprint < ApiBlueprint
|
||||
view :weapons do
|
||||
association :weapons,
|
||||
blueprint: GridWeaponBlueprint,
|
||||
view: :nested
|
||||
end
|
||||
|
||||
view :summons do
|
||||
association :summons,
|
||||
blueprint: GridSummonBlueprint,
|
||||
view: :nested
|
||||
end
|
||||
|
||||
view :characters do
|
||||
association :characters,
|
||||
blueprint: GridCharacterBlueprint,
|
||||
view: :nested
|
||||
end
|
||||
|
||||
view :job_skills do
|
||||
field :job_skills do |job|
|
||||
{
|
||||
'0' => !job.skill0.nil? ? JobSkillBlueprint.render_as_hash(job.skill0) : nil,
|
||||
'1' => !job.skill1.nil? ? JobSkillBlueprint.render_as_hash(job.skill1) : nil,
|
||||
'2' => !job.skill2.nil? ? JobSkillBlueprint.render_as_hash(job.skill2) : nil,
|
||||
'3' => !job.skill3.nil? ? JobSkillBlueprint.render_as_hash(job.skill3) : nil
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
view :minimal do
|
||||
fields :name, :element, :shortcode, :favorited, :extra, :created_at, :updated_at
|
||||
|
||||
association :raid,
|
||||
blueprint: RaidBlueprint
|
||||
|
||||
association :job,
|
||||
blueprint: JobBlueprint
|
||||
|
||||
association :user,
|
||||
blueprint: UserBlueprint,
|
||||
view: :minimal
|
||||
end
|
||||
|
||||
view :jobs do
|
||||
association :job,
|
||||
blueprint: JobBlueprint
|
||||
include_view :job_skills
|
||||
end
|
||||
|
||||
view :preview do
|
||||
include_view :minimal
|
||||
include_view :weapons
|
||||
end
|
||||
|
||||
view :full do
|
||||
include_view :preview
|
||||
include_view :summons
|
||||
include_view :characters
|
||||
include_view :job_skills
|
||||
|
||||
fields :description, :extra
|
||||
end
|
||||
|
||||
view :collection do
|
||||
include_view :preview
|
||||
end
|
||||
|
||||
view :destroyed do
|
||||
fields :name, :description, :created_at, :updated_at
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
16
app/blueprints/api/v1/raid_blueprint.rb
Normal file
16
app/blueprints/api/v1/raid_blueprint.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class RaidBlueprint < ApiBlueprint
|
||||
field :name do |raid|
|
||||
{
|
||||
en: raid.name_en,
|
||||
ja: raid.name_jp
|
||||
}
|
||||
end
|
||||
|
||||
fields :slug, :level, :group, :element
|
||||
end
|
||||
end
|
||||
end
|
||||
41
app/blueprints/api/v1/summon_blueprint.rb
Normal file
41
app/blueprints/api/v1/summon_blueprint.rb
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class SummonBlueprint < ApiBlueprint
|
||||
field :name do |w|
|
||||
{
|
||||
en: w.name_en,
|
||||
ja: w.name_jp
|
||||
}
|
||||
end
|
||||
|
||||
fields :granblue_id, :element, :rarity, :max_level
|
||||
|
||||
field :uncap do |w|
|
||||
{
|
||||
flb: w.flb,
|
||||
ulb: w.ulb
|
||||
}
|
||||
end
|
||||
|
||||
field :hp do |w|
|
||||
{
|
||||
min_hp: w.min_hp,
|
||||
max_hp: w.max_hp,
|
||||
max_hp_flb: w.max_hp_flb,
|
||||
max_hp_ulb: w.max_hp_ulb
|
||||
}
|
||||
end
|
||||
|
||||
field :atk do |w|
|
||||
{
|
||||
min_atk: w.min_atk,
|
||||
max_atk: w.max_atk,
|
||||
max_atk_flb: w.max_atk_flb,
|
||||
max_atk_ulb: w.max_atk_ulb
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
33
app/blueprints/api/v1/user_blueprint.rb
Normal file
33
app/blueprints/api/v1/user_blueprint.rb
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class UserBlueprint < ApiBlueprint
|
||||
view :minimal do
|
||||
fields :username, :language, :private, :gender
|
||||
field :avatar do |user|
|
||||
{
|
||||
picture: user.picture,
|
||||
element: user.element
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
view :profile do
|
||||
include_view :minimal
|
||||
|
||||
field :parties, if: ->(_fn, _obj, options) { options[:parties].length.positive? } do |_, options|
|
||||
PartyBlueprint.render_as_hash(options[:parties], view: :preview)
|
||||
end
|
||||
end
|
||||
|
||||
view :token do
|
||||
fields :username, :token
|
||||
end
|
||||
|
||||
view :settings do
|
||||
fields :email
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
43
app/blueprints/api/v1/weapon_blueprint.rb
Normal file
43
app/blueprints/api/v1/weapon_blueprint.rb
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class WeaponBlueprint < ApiBlueprint
|
||||
field :name do |w|
|
||||
{
|
||||
en: w.name_en,
|
||||
ja: w.name_jp
|
||||
}
|
||||
end
|
||||
|
||||
fields :granblue_id, :element, :proficiency,
|
||||
:max_level, :max_skill_level, :limit, :rarity,
|
||||
:series, :ax
|
||||
|
||||
field :uncap do |w|
|
||||
{
|
||||
flb: w.flb,
|
||||
ulb: w.ulb
|
||||
}
|
||||
end
|
||||
|
||||
field :hp do |w|
|
||||
{
|
||||
min_hp: w.min_hp,
|
||||
max_hp: w.max_hp,
|
||||
max_hp_flb: w.max_hp_flb,
|
||||
max_hp_ulb: w.max_hp_ulb
|
||||
}
|
||||
end
|
||||
|
||||
field :atk do |w|
|
||||
{
|
||||
min_atk: w.min_atk,
|
||||
max_atk: w.max_atk,
|
||||
max_atk_flb: w.max_atk_flb,
|
||||
max_atk_ulb: w.max_atk_ulb
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
16
app/blueprints/api/v1/weapon_key_blueprint.rb
Normal file
16
app/blueprints/api/v1/weapon_key_blueprint.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class WeaponKeyBlueprint < ApiBlueprint
|
||||
field :name do |key|
|
||||
{
|
||||
en: key.name_en,
|
||||
ja: key.name_jp
|
||||
}
|
||||
end
|
||||
|
||||
fields :series, :slot, :group, :order
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,80 +1,100 @@
|
|||
module Api::V1
|
||||
class ApiController < ActionController::API
|
||||
##### Doorkeeper
|
||||
include Doorkeeper::Rails::Helpers
|
||||
# frozen_string_literal: true
|
||||
|
||||
##### Errors
|
||||
rescue_from ActiveRecord::RecordInvalid, with: :render_unprocessable_entity_response
|
||||
rescue_from ActiveRecord::RecordNotDestroyed, with: :render_unprocessable_entity_response
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :render_not_found_response
|
||||
rescue_from ActiveRecord::RecordNotSaved, with: :render_unprocessable_entity_response
|
||||
rescue_from ActiveRecord::RecordNotUnique, with: :render_unprocessable_entity_response
|
||||
rescue_from Api::V1::SameFavoriteUserError, with: :render_unprocessable_entity_response
|
||||
rescue_from Api::V1::FavoriteAlreadyExistsError, with: :render_unprocessable_entity_response
|
||||
rescue_from Api::V1::NoJobProvidedError, with: :render_unprocessable_entity_response
|
||||
rescue_from Api::V1::TooManySkillsOfTypeError, with: :render_unprocessable_entity_response
|
||||
rescue_from Api::V1::UnauthorizedError, with: :render_unauthorized_response
|
||||
rescue_from ActionController::ParameterMissing, with: :render_unprocessable_entity_response
|
||||
module Api
|
||||
module V1
|
||||
class ApiController < ActionController::API
|
||||
##### Doorkeeper
|
||||
include Doorkeeper::Rails::Helpers
|
||||
|
||||
rescue_from GranblueError do |e|
|
||||
render_error(e)
|
||||
end
|
||||
##### Errors
|
||||
rescue_from ActiveRecord::RecordInvalid, with: :render_unprocessable_entity_response
|
||||
rescue_from ActiveRecord::RecordNotDestroyed, with: :render_unprocessable_entity_response
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :render_not_found_response_without_object
|
||||
rescue_from ActiveRecord::RecordNotSaved, with: :render_unprocessable_entity_response
|
||||
rescue_from ActiveRecord::RecordNotUnique, with: :render_unprocessable_entity_response
|
||||
rescue_from Api::V1::SameFavoriteUserError, with: :render_unprocessable_entity_response
|
||||
rescue_from Api::V1::FavoriteAlreadyExistsError, with: :render_unprocessable_entity_response
|
||||
rescue_from Api::V1::NoJobProvidedError, with: :render_unprocessable_entity_response
|
||||
rescue_from Api::V1::TooManySkillsOfTypeError, with: :render_unprocessable_entity_response
|
||||
rescue_from Api::V1::UnauthorizedError, with: :render_unauthorized_response
|
||||
rescue_from ActionController::ParameterMissing, with: :render_unprocessable_entity_response
|
||||
|
||||
##### Hooks
|
||||
before_action :current_user
|
||||
before_action :set_default_content_type
|
||||
|
||||
##### Responders
|
||||
respond_to :json
|
||||
|
||||
##### Methods
|
||||
# Assign the current user if the Doorkeeper token isn't nil, then
|
||||
# update the current user's last seen datetime and last IP address
|
||||
# before returning
|
||||
def current_user
|
||||
@current_user ||= User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
|
||||
|
||||
return @current_user
|
||||
end
|
||||
|
||||
# Set the response content-type
|
||||
def set_content_type(content_type)
|
||||
response.headers["Content-Type"] = content_type
|
||||
end
|
||||
|
||||
# Set the default response content-type to application/javascript
|
||||
# with a UTF-8 charset
|
||||
def set_default_content_type
|
||||
set_content_type("application/javascript; charset=utf-8")
|
||||
end
|
||||
|
||||
### Error response methods
|
||||
def render_error(error)
|
||||
if error
|
||||
render action: 'errors', json: error.to_hash, status: error.http_status
|
||||
else
|
||||
render action: 'errors'
|
||||
rescue_from GranblueError do |e|
|
||||
render_error(e)
|
||||
end
|
||||
end
|
||||
|
||||
def render_unprocessable_entity_response(exception)
|
||||
@exception = exception
|
||||
render action: 'errors', status: :unprocessable_entity
|
||||
end
|
||||
##### Hooks
|
||||
before_action :current_user
|
||||
before_action :default_content_type
|
||||
|
||||
def render_not_found_response
|
||||
response = { errors: [{ message: "Record could not be found.", code: "not_found" }] }
|
||||
render 'not_found', status: :not_found
|
||||
end
|
||||
##### Responders
|
||||
respond_to :json
|
||||
|
||||
def render_unauthorized_response
|
||||
render action: 'errors', status: :unauthorized
|
||||
end
|
||||
##### Methods
|
||||
# Assign the current user if the Doorkeeper token isn't nil, then
|
||||
# update the current user's last seen datetime and last IP address
|
||||
# before returning
|
||||
def current_user
|
||||
@current_user ||= User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
|
||||
|
||||
private
|
||||
@current_user
|
||||
end
|
||||
|
||||
def restrict_access
|
||||
raise UnauthorizedError unless current_user
|
||||
# Set the response content-type
|
||||
def content_type(content_type)
|
||||
response.headers['Content-Type'] = content_type
|
||||
end
|
||||
|
||||
# Set the default response content-type to application/javascript
|
||||
# with a UTF-8 charset
|
||||
def default_content_type
|
||||
content_type('application/javascript; charset=utf-8')
|
||||
end
|
||||
|
||||
### Error response methods
|
||||
def render_error(error)
|
||||
if error
|
||||
render action: 'errors', json: error.to_hash, status: error.http_status
|
||||
else
|
||||
render action: 'errors'
|
||||
end
|
||||
end
|
||||
|
||||
def render_unprocessable_entity_response(exception)
|
||||
render json: ErrorBlueprint.render_as_json(nil, exception: exception),
|
||||
status: :unprocessable_entity
|
||||
end
|
||||
|
||||
def render_validation_error_response(object)
|
||||
render json: ErrorBlueprint.render_as_json(nil, errors: object.errors),
|
||||
status: :unprocessable_entity
|
||||
end
|
||||
|
||||
def render_not_found_response_without_object
|
||||
render json: ErrorBlueprint.render(nil,
|
||||
error: {
|
||||
message: 'Object could not be found',
|
||||
code: 'not_found'
|
||||
}), status: :not_found
|
||||
end
|
||||
|
||||
def render_not_found_response(object)
|
||||
render json: ErrorBlueprint.render(nil, error: {
|
||||
message: "#{object.capitalize} could not be found",
|
||||
code: 'not_found'
|
||||
}), status: :not_found
|
||||
end
|
||||
|
||||
def render_unauthorized_response
|
||||
render json: ErrorBlueprint.render_as_json(nil),
|
||||
status: :unauthorized
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def restrict_access
|
||||
raise UnauthorizedError unless current_user
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,41 +1,51 @@
|
|||
class Api::V1::FavoritesController < Api::V1::ApiController
|
||||
before_action :set_party, only: ['create']
|
||||
# frozen_string_literal: true
|
||||
|
||||
def create
|
||||
module Api
|
||||
module V1
|
||||
class FavoritesController < Api::V1::ApiController
|
||||
before_action :set_party, only: ['create']
|
||||
|
||||
def create
|
||||
party_id = favorite_params[:party_id]
|
||||
party = Party.find(party_id)
|
||||
|
||||
if !current_user
|
||||
raise Api::V1::UnauthorizedError
|
||||
elsif party.user && current_user.id == party.user.id
|
||||
raise Api::V1::SameFavoriteUserError
|
||||
elsif Favorite.where(user_id: current_user.id, party_id: party_id).length > 0
|
||||
raise Api::V1::FavoriteAlreadyExistsError
|
||||
else
|
||||
object = {
|
||||
user_id: current_user.id,
|
||||
party_id: favorite_params[:party_id]
|
||||
}
|
||||
raise Api::V1::UnauthorizedError unless current_user
|
||||
raise Api::V1::SameFavoriteUserError if party.user && current_user.id == party.user.id
|
||||
raise Api::V1::FavoriteAlreadyExistsError if Favorite.where(user_id: current_user.id,
|
||||
party_id: party_id).length.positive?
|
||||
|
||||
@favorite = Favorite.new(object)
|
||||
render :show, status: :created if @favorite.save!
|
||||
@favorite = Favorite.new({
|
||||
user_id: current_user.id,
|
||||
party_id: party_id
|
||||
})
|
||||
|
||||
if @favorite.save!
|
||||
return render json: FavoriteBlueprint.render(@favorite, root: :favorite),
|
||||
status: :created
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
render_validation_error_response(@favorite)
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise Api::V1::UnauthorizedError unless current_user
|
||||
|
||||
@favorite = Favorite.where(user_id: current_user.id, party_id: favorite_params[:party_id]).first
|
||||
render :destroyed, status: :ok if @favorite && Favorite.destroy(@favorite.id)
|
||||
end
|
||||
render_not_found_response('favorite') unless @favorite
|
||||
|
||||
private
|
||||
render_error("Couldn't delete favorite") unless Favorite.destroy(@favorite.id)
|
||||
render json: FavoriteBlueprint.render(@favorite, root: :favorite, view: :destroyed)
|
||||
end
|
||||
|
||||
def set_party
|
||||
@party = Party.where("id = ?", params[:party_id]).first
|
||||
end
|
||||
private
|
||||
|
||||
def favorite_params
|
||||
def set_party
|
||||
@party = Party.where('id = ?', params[:party_id]).first
|
||||
end
|
||||
|
||||
def favorite_params
|
||||
params.require(:favorite).permit(:party_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,53 +1,53 @@
|
|||
class Api::V1::GridCharactersController < Api::V1::ApiController
|
||||
def create
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class GridCharactersController < Api::V1::ApiController
|
||||
def create
|
||||
party = Party.find(character_params[:party_id])
|
||||
incoming_character = Character.find(character_params[:character_id])
|
||||
|
||||
if current_user
|
||||
if party.user != current_user
|
||||
render_unauthorized_response
|
||||
end
|
||||
end
|
||||
render_unauthorized_response if current_user && (party.user != current_user)
|
||||
|
||||
current_characters = party.characters.map { |c|
|
||||
Character.find(c.character.id).character_id
|
||||
}.flatten
|
||||
current_characters = party.characters.map do |c|
|
||||
Character.find(c.character.id).character_id
|
||||
end.flatten
|
||||
|
||||
# Check all character ids on incoming character against current characters
|
||||
conflict_ids = (current_characters & incoming_character.character_id)
|
||||
|
||||
if conflict_ids.length > 0
|
||||
# Find conflicting character ids in party characters
|
||||
conflict_characters = party.characters.filter { |c|
|
||||
c if (conflict_ids & c.character.character_id).length > 0
|
||||
}.flatten
|
||||
|
||||
# Render a template with the conflicting and incoming characters,
|
||||
# as well as the selected position, so the user can be presented with
|
||||
# a decision.
|
||||
if conflict_ids.length.positive?
|
||||
# Find conflicting character ids in party characters
|
||||
conflict_characters = party.characters.filter do |c|
|
||||
c if (conflict_ids & c.character.character_id).length.positive?
|
||||
end.flatten
|
||||
|
||||
# Up to 3 characters can be removed at the same time
|
||||
@conflict_characters = conflict_characters
|
||||
@incoming_character = incoming_character
|
||||
@incoming_position = character_params[:position]
|
||||
# Render a template with the conflicting and incoming characters,
|
||||
# as well as the selected position, so the user can be presented with
|
||||
# a decision.
|
||||
|
||||
render :conflict, status: :ok
|
||||
# Up to 3 characters can be removed at the same time
|
||||
render json: ConflictBlueprint.render(nil, view: :characters,
|
||||
conflict_characters: conflict_characters,
|
||||
incoming_character: incoming_character,
|
||||
incoming_position: character_params[:position])
|
||||
else
|
||||
# Replace the grid character in the position if it is already filled
|
||||
if GridCharacter.where(party_id: party.id, position: character_params[:position]).exists?
|
||||
@character = GridCharacter.where(party_id: party.id, position: character_params[:position]).limit(1)[0]
|
||||
@character.character_id = incoming_character.id
|
||||
# Replace the grid character in the position if it is already filled
|
||||
if GridCharacter.where(party_id: party.id, position: character_params[:position]).exists?
|
||||
character = GridCharacter.where(party_id: party.id, position: character_params[:position]).limit(1)[0]
|
||||
character.character_id = incoming_character.id
|
||||
|
||||
# Otherwise, create a new grid character
|
||||
else
|
||||
@character = GridCharacter.create!(character_params.merge(party_id: party.id, character_id: incoming_character.id))
|
||||
end
|
||||
else
|
||||
character = GridCharacter.create!(character_params.merge(party_id: party.id,
|
||||
character_id: incoming_character.id))
|
||||
end
|
||||
|
||||
render :show, status: :created if @character.save!
|
||||
render json: GridCharacterBlueprint.render(character, view: :nested), status: :created if character.save!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def resolve
|
||||
def resolve
|
||||
incoming = Character.find(resolve_params[:incoming])
|
||||
conflicting = resolve_params[:conflicting].map { |id| GridCharacter.find(id) }
|
||||
party = conflicting.first.party
|
||||
|
|
@ -57,46 +57,48 @@ class Api::V1::GridCharactersController < Api::V1::ApiController
|
|||
|
||||
# Destroy the character at the desired position if it exists
|
||||
existing_character = GridCharacter.where(party: party.id, position: resolve_params[:position]).first
|
||||
GridCharacter.destroy(existing_character.id) unless !existing_character
|
||||
GridCharacter.destroy(existing_character.id) if existing_character
|
||||
|
||||
if (incoming.special)
|
||||
uncap_level = 3
|
||||
uncap_level = 5 if incoming.ulb
|
||||
uncap_level = 4 if incoming.flb
|
||||
if incoming.special
|
||||
uncap_level = 3
|
||||
uncap_level = 5 if incoming.ulb
|
||||
uncap_level = 4 if incoming.flb
|
||||
else
|
||||
uncap_level = 4
|
||||
uncap_level = 6 if incoming.ulb
|
||||
uncap_level = 5 if incoming.flb
|
||||
end
|
||||
|
||||
@character = GridCharacter.create!(party_id: party.id, character_id: incoming.id, position: resolve_params[:position], uncap_level: uncap_level)
|
||||
render :show, status: :created if @character.save!
|
||||
end
|
||||
|
||||
def update_uncap_level
|
||||
@character = GridCharacter.find(character_params[:id])
|
||||
|
||||
if current_user
|
||||
if @character.party.user != current_user
|
||||
render_unauthorized_response
|
||||
end
|
||||
uncap_level = 4
|
||||
uncap_level = 6 if incoming.ulb
|
||||
uncap_level = 5 if incoming.flb
|
||||
end
|
||||
|
||||
@character.uncap_level = character_params[:uncap_level]
|
||||
render :show, status: :ok if @character.save!
|
||||
end
|
||||
character = GridCharacter.create!(party_id: party.id, character_id: incoming.id,
|
||||
position: resolve_params[:position], uncap_level: uncap_level)
|
||||
render json: GridCharacterBlueprint.render(character, view: :nested), status: :created if character.save!
|
||||
end
|
||||
|
||||
def destroy
|
||||
end
|
||||
def update_uncap_level
|
||||
character = GridCharacter.find(character_params[:id])
|
||||
|
||||
private
|
||||
render_unauthorized_response if current_user && (character.party.user != current_user)
|
||||
|
||||
# Specify whitelisted properties that can be modified.
|
||||
def character_params
|
||||
params.require(:character).permit(:id, :party_id, :character_id, :position, :uncap_level, :conflicting, :incoming)
|
||||
end
|
||||
character.uncap_level = character_params[:uncap_level]
|
||||
return unless character.save!
|
||||
|
||||
def resolve_params
|
||||
params.require(:resolve).permit(:position, :incoming, :conflicting => [])
|
||||
render json: GridCharacterBlueprint.render(character, view: :nested, root: :grid_character)
|
||||
end
|
||||
|
||||
# TODO: Implement removing characters
|
||||
def destroy; end
|
||||
|
||||
private
|
||||
|
||||
# Specify whitelisted properties that can be modified.
|
||||
def character_params
|
||||
params.require(:character).permit(:id, :party_id, :character_id, :position, :uncap_level, :conflicting,
|
||||
:incoming)
|
||||
end
|
||||
|
||||
def resolve_params
|
||||
params.require(:resolve).permit(:position, :incoming, conflicting: [])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,45 +1,45 @@
|
|||
class Api::V1::GridSummonsController < Api::V1::ApiController
|
||||
def create
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class GridSummonsController < Api::V1::ApiController
|
||||
def create
|
||||
party = Party.find(summon_params[:party_id])
|
||||
canonical_summon = Summon.find(summon_params[:summon_id])
|
||||
|
||||
if current_user
|
||||
if party.user != current_user
|
||||
render_unauthorized_response
|
||||
end
|
||||
|
||||
render_unauthorized_response if current_user && (party.user != current_user)
|
||||
|
||||
if (grid_summon = GridSummon.where(
|
||||
party_id: party.id,
|
||||
position: summon_params[:position]
|
||||
).first)
|
||||
GridSummon.destroy(grid_summon.id)
|
||||
end
|
||||
|
||||
if grid_summon = GridSummon.where(
|
||||
party_id: party.id,
|
||||
position: summon_params[:position]
|
||||
).first
|
||||
GridSummon.destroy(grid_summon.id)
|
||||
end
|
||||
summon = GridSummon.create!(summon_params.merge(party_id: party.id, summon_id: canonical_summon.id))
|
||||
render json: GridSummonBlueprint.render(summon, view: :nested), status: :created if summon.save!
|
||||
end
|
||||
|
||||
@summon = GridSummon.create!(summon_params.merge(party_id: party.id, summon_id: canonical_summon.id))
|
||||
render :show, status: :created if @summon.save!
|
||||
end
|
||||
|
||||
def update_uncap_level
|
||||
@summon = GridSummon.find(summon_params[:id])
|
||||
def update_uncap_level
|
||||
summon = GridSummon.find(summon_params[:id])
|
||||
|
||||
if current_user
|
||||
if @summon.party.user != current_user
|
||||
render_unauthorized_response
|
||||
end
|
||||
end
|
||||
render_unauthorized_response if current_user && (summon.party.user != current_user)
|
||||
|
||||
@summon.uncap_level = summon_params[:uncap_level]
|
||||
render :show, status: :ok if @summon.save!
|
||||
end
|
||||
summon.uncap_level = summon_params[:uncap_level]
|
||||
return unless summon.save!
|
||||
|
||||
def destroy
|
||||
end
|
||||
render json: GridSummonBlueprint.render(summon, view: :nested, root: :grid_summon)
|
||||
end
|
||||
|
||||
private
|
||||
# TODO: Implement removing summons
|
||||
def destroy; end
|
||||
|
||||
# Specify whitelisted properties that can be modified.
|
||||
def summon_params
|
||||
private
|
||||
|
||||
# Specify whitelisted properties that can be modified.
|
||||
def summon_params
|
||||
params.require(:summon).permit(:id, :party_id, :summon_id, :position, :main, :friend, :uncap_level)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,39 +1,35 @@
|
|||
class Api::V1::GridWeaponsController < Api::V1::ApiController
|
||||
before_action :set, except: ['create', 'update_uncap_level', 'destroy']
|
||||
# frozen_string_literal: true
|
||||
|
||||
def create
|
||||
module Api
|
||||
module V1
|
||||
class GridWeaponsController < Api::V1::ApiController
|
||||
before_action :set, except: %w[create update_uncap_level destroy]
|
||||
|
||||
def create
|
||||
party = Party.find(weapon_params[:party_id])
|
||||
canonical_weapon = Weapon.find(weapon_params[:weapon_id])
|
||||
|
||||
if current_user
|
||||
if party.user != current_user
|
||||
render_unauthorized_response
|
||||
end
|
||||
render_unauthorized_response if current_user && (party.user != current_user)
|
||||
|
||||
if (grid_weapon = GridWeapon.where(
|
||||
party_id: party.id,
|
||||
position: weapon_params[:position]
|
||||
).first)
|
||||
GridWeapon.destroy(grid_weapon.id)
|
||||
end
|
||||
|
||||
if grid_weapon = GridWeapon.where(
|
||||
party_id: party.id,
|
||||
position: weapon_params[:position]
|
||||
).first
|
||||
GridWeapon.destroy(grid_weapon.id)
|
||||
weapon = GridWeapon.create!(weapon_params.merge(party_id: party.id, weapon_id: canonical_weapon.id))
|
||||
|
||||
if weapon.position == -1
|
||||
party.element = weapon.weapon.element
|
||||
party.save!
|
||||
end
|
||||
|
||||
@weapon = GridWeapon.create!(weapon_params.merge(party_id: party.id, weapon_id: canonical_weapon.id))
|
||||
render json: GridWeaponBlueprint.render(weapon, view: :full), status: :created if weapon.save!
|
||||
end
|
||||
|
||||
if (@weapon.position == -1)
|
||||
party.element = @weapon.weapon.element
|
||||
party.save!
|
||||
end
|
||||
|
||||
render :show, status: :created if @weapon.save!
|
||||
end
|
||||
|
||||
def update
|
||||
if current_user
|
||||
if @weapon.party.user != current_user
|
||||
render_unauthorized_response
|
||||
end
|
||||
end
|
||||
def update
|
||||
render_unauthorized_response if current_user && (@weapon.party.user != current_user)
|
||||
|
||||
# TODO: Server-side validation of weapon mods
|
||||
# We don't want someone modifying the JSON and adding
|
||||
|
|
@ -41,35 +37,39 @@ class Api::V1::GridWeaponsController < Api::V1::ApiController
|
|||
|
||||
# Maybe we make methods on the model to validate for us somehow
|
||||
|
||||
render :update, status: :ok if @weapon.update(weapon_params)
|
||||
end
|
||||
render json: GridWeaponBlueprint.render(@weapon, view: :nested) if @weapon.update(weapon_params)
|
||||
end
|
||||
|
||||
def update_uncap_level
|
||||
@weapon = GridWeapon.find(weapon_params[:id])
|
||||
# TODO: Implement removing characters
|
||||
def destroy; end
|
||||
|
||||
if current_user
|
||||
if party.user != current_user
|
||||
render_unauthorized_response
|
||||
end
|
||||
end
|
||||
def update_uncap_level
|
||||
weapon = GridWeapon.find(weapon_params[:id])
|
||||
|
||||
@weapon.uncap_level = weapon_params[:uncap_level]
|
||||
render :show, status: :ok if @weapon.save!
|
||||
end
|
||||
render_unauthorized_response if current_user && (weapon.party.user != current_user)
|
||||
|
||||
private
|
||||
weapon.uncap_level = weapon_params[:uncap_level]
|
||||
return unless weapon.save!
|
||||
|
||||
def set
|
||||
@weapon = GridWeapon.where("id = ?", params[:id]).first
|
||||
end
|
||||
render json: GridWeaponBlueprint.render(weapon, view: :nested, root: :grid_weapon),
|
||||
status: :created
|
||||
end
|
||||
|
||||
# Specify whitelisted properties that can be modified.
|
||||
def weapon_params
|
||||
private
|
||||
|
||||
def set
|
||||
@weapon = GridWeapon.where('id = ?', params[:id]).first
|
||||
end
|
||||
|
||||
# Specify whitelisted properties that can be modified.
|
||||
def weapon_params
|
||||
params.require(:weapon).permit(
|
||||
:id, :party_id, :weapon_id,
|
||||
:position, :mainhand, :uncap_level, :element,
|
||||
:weapon_key1_id, :weapon_key2_id, :weapon_key3_id,
|
||||
:ax_modifier1, :ax_modifier2, :ax_strength1, :ax_strength2
|
||||
:id, :party_id, :weapon_id,
|
||||
:position, :mainhand, :uncap_level, :element,
|
||||
:weapon_key1_id, :weapon_key2_id, :weapon_key3_id,
|
||||
:ax_modifier1, :ax_modifier2, :ax_strength1, :ax_strength2
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
class Api::V1::JobSkillsController < Api::V1::ApiController
|
||||
def all
|
||||
@skills = JobSkill.all()
|
||||
render :all, status: :ok
|
||||
end
|
||||
# frozen_string_literal: true
|
||||
|
||||
def job
|
||||
job = Job.find(params[:id])
|
||||
module Api
|
||||
module V1
|
||||
class JobSkillsController < Api::V1::ApiController
|
||||
def all
|
||||
render json: JobSkillBlueprint.render(JobSkill.all)
|
||||
end
|
||||
|
||||
@skills = JobSkill.where(job: job).or(JobSkill.where(sub: true))
|
||||
render :all, status: :ok
|
||||
def job
|
||||
@skills = JobSkill.where('job_id != ? AND emp = ?', params[:id], true)
|
||||
render json: JobSkillBlueprint.render(@skills)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,160 +1,180 @@
|
|||
class Api::V1::JobsController < Api::V1::ApiController
|
||||
before_action :set, only: %w[update_job update_job_skills]
|
||||
# frozen_string_literal: true
|
||||
|
||||
def all
|
||||
@jobs = Job.all()
|
||||
render :all, status: :ok
|
||||
end
|
||||
module Api
|
||||
module V1
|
||||
class JobsController < Api::V1::ApiController
|
||||
before_action :set, only: %w[update_job update_job_skills]
|
||||
|
||||
def update_job
|
||||
raise NoJobProvidedError unless job_params[:job_id].present?
|
||||
|
||||
# Extract job and find its main skills
|
||||
job = Job.find(job_params[:job_id])
|
||||
main_skills = JobSkill.where(job: job.id, main: true)
|
||||
|
||||
# Update the party
|
||||
@party.job = job
|
||||
main_skills.each_with_index do |skill, index|
|
||||
@party["skill#{index}_id"] = skill.id
|
||||
end
|
||||
|
||||
# Check for incompatible Base and EMP skills
|
||||
%w[skill1_id skill2_id skill3_id].each do |key|
|
||||
@party[key] = nil if @party[key] && mismatched_skill(@party.job, JobSkill.find(@party[key]))
|
||||
end
|
||||
|
||||
render :update, status: :ok if @party.save!
|
||||
end
|
||||
|
||||
def update_job_skills
|
||||
throw NoJobSkillProvidedError unless job_params[:skill1_id] || job_params[:skill2_id] || job_params[:skill3_id]
|
||||
|
||||
# Determine which incoming keys contain new skills
|
||||
skill_keys = %w[skill1_id skill2_id skill3_id]
|
||||
new_skill_keys = job_params.keys.select { |key| skill_keys.include?(key) }
|
||||
|
||||
# If there are new skills, merge them with the existing skills
|
||||
unless new_skill_keys.empty?
|
||||
existing_skills = {
|
||||
1 => @party.skill1,
|
||||
2 => @party.skill2,
|
||||
3 => @party.skill3
|
||||
}
|
||||
|
||||
new_skill_ids = new_skill_keys.map { |key| job_params[key] }
|
||||
new_skill_ids.map do |id|
|
||||
skill = JobSkill.find(id)
|
||||
raise Api::V1::IncompatibleSkillError.new(job: @party.job, skill: skill) if mismatched_skill(@party.job, skill)
|
||||
def all
|
||||
render json: JobBlueprint.render(Job.all)
|
||||
end
|
||||
|
||||
positions = extract_positions_from_keys(new_skill_keys)
|
||||
new_skills = merge_skills_with_existing_skills(existing_skills, new_skill_ids, positions)
|
||||
def update_job
|
||||
if job_params[:job_id] != -1
|
||||
# Extract job and find its main skills
|
||||
old_job = @party.job
|
||||
job = Job.find(job_params[:job_id])
|
||||
main_skills = JobSkill.where(job: job.id, main: true)
|
||||
|
||||
new_skill_ids = new_skills.each_with_object({}) do |(index, skill), memo|
|
||||
memo["skill#{index}_id"] = skill.id if skill
|
||||
# Update the party
|
||||
@party.job = job
|
||||
main_skills.each_with_index do |skill, index|
|
||||
@party["skill#{index}_id"] = skill.id
|
||||
end
|
||||
|
||||
# Check for incompatible Base and EMP skills
|
||||
%w[skill1_id skill2_id skill3_id].each do |key|
|
||||
@party[key] = nil if @party[key] && mismatched_skill(@party.job, JobSkill.find(@party[key]))
|
||||
end
|
||||
|
||||
# Remove extra subskills if necessary
|
||||
if old_job &&
|
||||
%w[1 2 3].include?(old_job.row) &&
|
||||
%w[4 5 ex2].include?(job.row) &&
|
||||
@party.skill1 && @party.skill2 && @party.skill3 &&
|
||||
@party.skill1.sub && @party.skill2.sub && @party.skill3.sub
|
||||
@party['skill3_id'] = nil
|
||||
end
|
||||
else
|
||||
@party.job = nil
|
||||
%w[skill0_id skill1_id skill2_id skill3_id].each do |key|
|
||||
@party[key] = nil
|
||||
end
|
||||
end
|
||||
|
||||
render json: PartyBlueprint.render(@party, view: :jobs) if @party.save!
|
||||
end
|
||||
|
||||
@party.attributes = new_skill_ids
|
||||
end
|
||||
def update_job_skills
|
||||
throw NoJobSkillProvidedError unless job_params[:skill1_id] || job_params[:skill2_id] || job_params[:skill3_id]
|
||||
|
||||
render :update, status: :ok if @party.save!
|
||||
end
|
||||
# Determine which incoming keys contain new skills
|
||||
skill_keys = %w[skill1_id skill2_id skill3_id]
|
||||
new_skill_keys = job_params.keys.select { |key| skill_keys.include?(key) }
|
||||
|
||||
private
|
||||
# If there are new skills, merge them with the existing skills
|
||||
unless new_skill_keys.empty?
|
||||
existing_skills = {
|
||||
1 => @party.skill1,
|
||||
2 => @party.skill2,
|
||||
3 => @party.skill3
|
||||
}
|
||||
|
||||
def merge_skills_with_existing_skills(
|
||||
existing_skills,
|
||||
new_skill_ids,
|
||||
positions
|
||||
)
|
||||
new_skills = new_skill_ids.map { |id| JobSkill.find(id) }
|
||||
new_skill_ids = new_skill_keys.map { |key| job_params[key] }
|
||||
new_skill_ids.map do |id|
|
||||
skill = JobSkill.find(id)
|
||||
raise Api::V1::IncompatibleSkillError.new(job: @party.job, skill: skill) if mismatched_skill(@party.job,
|
||||
skill)
|
||||
end
|
||||
|
||||
new_skills.each_with_index do |skill, index|
|
||||
existing_skills = place_skill_in_existing_skills(existing_skills, skill, positions[index])
|
||||
end
|
||||
positions = extract_positions_from_keys(new_skill_keys)
|
||||
new_skills = merge_skills_with_existing_skills(existing_skills, new_skill_ids, positions)
|
||||
|
||||
existing_skills
|
||||
end
|
||||
new_skill_ids = new_skills.each_with_object({}) do |(index, skill), memo|
|
||||
memo["skill#{index}_id"] = skill.id if skill
|
||||
end
|
||||
|
||||
def place_skill_in_existing_skills(existing_skills, skill, position)
|
||||
# Test if skill will exceed allowances of skill types
|
||||
skill_type = skill.sub ? 'sub' : 'emp'
|
||||
@party.attributes = new_skill_ids
|
||||
end
|
||||
|
||||
unless can_add_skill_of_type(existing_skills, position, skill_type)
|
||||
raise Api::V1::TooManySkillsOfTypeError.new(skill_type: skill_type)
|
||||
end
|
||||
render json: PartyBlueprint.render(@party, view: :jobs) if @party.save!
|
||||
end
|
||||
|
||||
if !existing_skills[position]
|
||||
existing_skills[position] = skill
|
||||
else
|
||||
value = existing_skills.compact.detect { |_, value| value && value.id == skill.id }
|
||||
old_position = existing_skills.key(value[1]) if value
|
||||
private
|
||||
|
||||
if old_position
|
||||
existing_skills = swap_skills_at_position(existing_skills, skill, position, old_position)
|
||||
else
|
||||
existing_skills[position] = skill
|
||||
def merge_skills_with_existing_skills(
|
||||
existing_skills,
|
||||
new_skill_ids,
|
||||
positions
|
||||
)
|
||||
new_skills = new_skill_ids.map { |id| JobSkill.find(id) }
|
||||
|
||||
new_skills.each_with_index do |skill, index|
|
||||
existing_skills = place_skill_in_existing_skills(existing_skills, skill, positions[index])
|
||||
end
|
||||
|
||||
existing_skills
|
||||
end
|
||||
|
||||
def place_skill_in_existing_skills(existing_skills, skill, position)
|
||||
# Test if skill will exceed allowances of skill types
|
||||
skill_type = skill.sub ? 'sub' : 'emp'
|
||||
|
||||
unless can_add_skill_of_type(existing_skills, position, skill_type)
|
||||
raise Api::V1::TooManySkillsOfTypeError.new(skill_type: skill_type)
|
||||
end
|
||||
|
||||
if !existing_skills[position]
|
||||
existing_skills[position] = skill
|
||||
else
|
||||
value = existing_skills.compact.detect { |_, value| value && value.id == skill.id }
|
||||
old_position = existing_skills.key(value[1]) if value
|
||||
|
||||
if old_position
|
||||
existing_skills = swap_skills_at_position(existing_skills, skill, position, old_position)
|
||||
else
|
||||
existing_skills[position] = skill
|
||||
end
|
||||
end
|
||||
|
||||
existing_skills
|
||||
end
|
||||
|
||||
def swap_skills_at_position(skills, new_skill, position1, position2)
|
||||
# Check desired position for a skill
|
||||
displaced_skill = skills[position1] if skills[position1].present?
|
||||
|
||||
# Put skill in new position
|
||||
skills[position1] = new_skill
|
||||
skills[position2] = displaced_skill
|
||||
|
||||
skills
|
||||
end
|
||||
|
||||
def extract_positions_from_keys(keys)
|
||||
# Subtract by 1 because we won't operate on the 0th skill, so we don't pass it
|
||||
keys.map { |key| key['skill'.length].to_i }
|
||||
end
|
||||
|
||||
def can_add_skill_of_type(skills, position, type)
|
||||
if %w[4 5 ex2].include?(@party.job.row) && skills.values.compact.length.positive?
|
||||
max_skill_of_type = 2
|
||||
skills_to_check = skills.compact.reject { |key, _| key == position }
|
||||
|
||||
sum = skills_to_check.values.count { |value| value.send(type) }
|
||||
return sum + 1 <= max_skill_of_type
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def mismatched_skill(job, skill)
|
||||
mismatched_main = (skill.job.id != job.id) && skill.main && !skill.sub
|
||||
mismatched_emp = (skill.job.id != job.id) && skill.emp
|
||||
mismatched_base = skill.job.base_job && (job.row != 'ex2' || skill.job.base_job.id != job.base_job.id) && skill.base
|
||||
|
||||
if %w[4 5 ex2].include?(job.row)
|
||||
true if mismatched_emp || mismatched_base || mismatched_main
|
||||
elsif mismatched_emp || mismatched_main
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def set
|
||||
@party = Party.where('id = ?', params[:id]).first
|
||||
end
|
||||
|
||||
def job_params
|
||||
params.require(:party).permit(
|
||||
:job_id,
|
||||
:skill0_id,
|
||||
:skill1_id,
|
||||
:skill2_id,
|
||||
:skill3_id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
existing_skills
|
||||
end
|
||||
|
||||
def swap_skills_at_position(skills, new_skill, position1, position2)
|
||||
# Check desired position for a skill
|
||||
displaced_skill = skills[position1] if skills[position1].present?
|
||||
|
||||
# Put skill in new position
|
||||
skills[position1] = new_skill
|
||||
skills[position2] = displaced_skill
|
||||
|
||||
skills
|
||||
end
|
||||
|
||||
def extract_positions_from_keys(keys)
|
||||
# Subtract by 1 because we won't operate on the 0th skill, so we don't pass it
|
||||
keys.map { |key| key['skill'.length].to_i }
|
||||
end
|
||||
|
||||
def can_add_skill_of_type(skills, position, type)
|
||||
if skills.values.compact.length.positive?
|
||||
max_skill_of_type = 2
|
||||
skills_to_check = skills.compact.reject { |key, _| key == position }
|
||||
|
||||
sum = skills_to_check.values.count { |value| value.send(type) }
|
||||
|
||||
sum + 1 <= max_skill_of_type
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def mismatched_skill(job, skill)
|
||||
mismatched_main = (skill.job.id != job.id) && skill.main && !skill.sub
|
||||
mismatched_emp = (skill.job.id != job.id) && skill.emp
|
||||
mismatched_base = skill.job.base_job && (job.row != 'ex2' || skill.job.base_job.id != job.base_job.id) && skill.base
|
||||
|
||||
if %w[4 5 ex2].include?(job.row)
|
||||
true if mismatched_emp || mismatched_base || mismatched_main
|
||||
elsif mismatched_emp || mismatched_main
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def set
|
||||
@party = Party.where('id = ?', params[:id]).first
|
||||
end
|
||||
|
||||
def job_params
|
||||
params.require(:party).permit(
|
||||
:job_id,
|
||||
:skill0_id,
|
||||
:skill1_id,
|
||||
:skill2_id,
|
||||
:skill3_id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,162 +1,150 @@
|
|||
class Api::V1::PartiesController < Api::V1::ApiController
|
||||
before_action :set_from_slug,
|
||||
except: %w[create destroy update index favorites]
|
||||
before_action :set, only: %w[update destroy]
|
||||
# frozen_string_literal: true
|
||||
|
||||
def create
|
||||
@party = Party.new(shortcode: random_string)
|
||||
@party.extra = party_params['extra']
|
||||
module Api
|
||||
module V1
|
||||
PER_PAGE = 15
|
||||
|
||||
job = Job.find(party_params['job_id']) if party_params['job_id'].present?
|
||||
if job
|
||||
job_skills = JobSkill.where(job: job.id, main: true)
|
||||
job_skills.each_with_index do |skill, index|
|
||||
@party["skill#{index}_id"] = skill.id
|
||||
class PartiesController < Api::V1::ApiController
|
||||
before_action :set_from_slug,
|
||||
except: %w[create destroy update index favorites]
|
||||
before_action :set, only: %w[update destroy]
|
||||
|
||||
def create
|
||||
@party = Party.new(shortcode: random_string)
|
||||
@party.extra = party_params['extra']
|
||||
|
||||
# TODO: Extract this into a different method
|
||||
job = Job.find(party_params['job_id']) if party_params['job_id'].present?
|
||||
if job
|
||||
job_skills = JobSkill.where(job: job.id, main: true)
|
||||
job_skills.each_with_index do |skill, index|
|
||||
@party["skill#{index}_id"] = skill.id
|
||||
end
|
||||
end
|
||||
|
||||
@party.user = current_user if current_user
|
||||
|
||||
if @party.save!
|
||||
return render json: PartyBlueprint.render(@party, view: :full, root: :party),
|
||||
status: :created
|
||||
end
|
||||
|
||||
render_validation_error_response(@party)
|
||||
end
|
||||
|
||||
def show
|
||||
return render json: PartyBlueprint.render(@party, view: :full, root: :party) if @party
|
||||
|
||||
render_not_found_response('project')
|
||||
end
|
||||
|
||||
def update
|
||||
render_unauthorized_response if @party.user != current_user
|
||||
|
||||
@party.attributes = party_params.except(:skill1_id, :skill2_id, :skill3_id)
|
||||
|
||||
return render json: PartyBlueprint.render(@party, view: :full, root: :party) if @party.save!
|
||||
|
||||
render_validation_error_response(@party)
|
||||
end
|
||||
|
||||
def destroy
|
||||
render_unauthorized_response if @party.user != current_user
|
||||
return render json: PartyBlueprint.render(@party, view: :destroyed, root: :checkin) if @party.destroy
|
||||
end
|
||||
|
||||
def index
|
||||
conditions = build_conditions(request.params)
|
||||
ap conditions
|
||||
|
||||
@parties = Party.where(conditions)
|
||||
.order(created_at: :desc)
|
||||
.paginate(page: request.params[:page], per_page: PER_PAGE)
|
||||
.each { |party| party.favorited = current_user ? party.is_favorited(current_user) : false }
|
||||
|
||||
count = Party.where(conditions).count
|
||||
total_pages = count.to_f / PER_PAGE > 1 ? (count.to_f / PER_PAGE).ceil : 1
|
||||
|
||||
render json: PartyBlueprint.render(@parties,
|
||||
view: :collection,
|
||||
root: :results,
|
||||
meta: {
|
||||
count: count,
|
||||
total_pages: total_pages,
|
||||
per_page: PER_PAGE
|
||||
})
|
||||
end
|
||||
|
||||
def favorites
|
||||
raise Api::V1::UnauthorizedError unless current_user
|
||||
|
||||
conditions = build_conditions(request.params)
|
||||
conditions[:favorites] = { user_id: current_user.id }
|
||||
|
||||
@parties = Party.joins(:favorites)
|
||||
.where(conditions)
|
||||
.order('favorites.created_at DESC')
|
||||
.paginate(page: request.params[:page], per_page: PER_PAGE)
|
||||
.each { |party| party.favorited = party.is_favorited(current_user) }
|
||||
|
||||
count = Party.joins(:favorites).where(conditions).count
|
||||
total_pages = count.to_f / PER_PAGE > 1 ? (count.to_f / PER_PAGE).ceil : 1
|
||||
|
||||
render json: PartyBlueprint.render(@parties,
|
||||
view: :collection,
|
||||
root: :results,
|
||||
meta: {
|
||||
count: count,
|
||||
total_pages: total_pages,
|
||||
per_page: PER_PAGE
|
||||
})
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_conditions(params)
|
||||
unless params['recency'].blank?
|
||||
start_time = (DateTime.current - params['recency'].to_i.seconds)
|
||||
.to_datetime.beginning_of_day
|
||||
end
|
||||
|
||||
{}.tap do |hash|
|
||||
hash[:element] = params['element'] unless params['element'].blank?
|
||||
hash[:raid] = params['raid'] unless params['raid'].blank?
|
||||
hash[:created_at] = start_time..DateTime.current unless params['recency'].blank?
|
||||
hash[:weapons_count] = 5..13
|
||||
end
|
||||
end
|
||||
|
||||
def random_string
|
||||
num_chars = 6
|
||||
o = [('a'..'z'), ('A'..'Z'), (0..9)].map(&:to_a).flatten
|
||||
(0...num_chars).map { o[rand(o.length)] }.join
|
||||
end
|
||||
|
||||
def set_from_slug
|
||||
@party = Party.where('shortcode = ?', params[:id]).first
|
||||
@party.favorited = current_user && @party ? @party.is_favorited(current_user) : false
|
||||
end
|
||||
|
||||
def set
|
||||
@party = Party.where('id = ?', params[:id]).first
|
||||
end
|
||||
|
||||
def party_params
|
||||
params.require(:party).permit(
|
||||
:user_id,
|
||||
:extra,
|
||||
:name,
|
||||
:description,
|
||||
:raid_id,
|
||||
:job_id,
|
||||
:skill0_id,
|
||||
:skill1_id,
|
||||
:skill2_id,
|
||||
:skill3_id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@party.user = current_user if current_user
|
||||
|
||||
render :show, status: :created if @party.save!
|
||||
end
|
||||
|
||||
def show
|
||||
render_not_found_response if @party.nil?
|
||||
end
|
||||
|
||||
def update
|
||||
if @party.user != current_user
|
||||
render_unauthorized_response
|
||||
else
|
||||
@party.attributes = party_params.except(:skill1_id, :skill2_id, :skill3_id)
|
||||
end
|
||||
|
||||
render :update, status: :ok if @party.save!
|
||||
end
|
||||
|
||||
def index
|
||||
@per_page = 15
|
||||
|
||||
now = DateTime.current
|
||||
start_time =
|
||||
(
|
||||
now - request.params["recency"].to_i.seconds
|
||||
).to_datetime.beginning_of_day unless request.params["recency"].blank?
|
||||
|
||||
conditions = {}
|
||||
conditions[:element] = request.params["element"] unless request.params[
|
||||
"element"
|
||||
].blank?
|
||||
conditions[:raid] = request.params["raid"] unless request.params[
|
||||
"raid"
|
||||
].blank?
|
||||
conditions[:created_at] = start_time..now unless request.params[
|
||||
"recency"
|
||||
].blank?
|
||||
conditions[:weapons_count] = 5..13
|
||||
|
||||
@parties =
|
||||
Party
|
||||
.where(conditions)
|
||||
.order(created_at: :desc)
|
||||
.paginate(page: request.params[:page], per_page: @per_page)
|
||||
.each do |party|
|
||||
party.favorited =
|
||||
current_user ? party.is_favorited(current_user) : false
|
||||
end
|
||||
@count = Party.where(conditions).count
|
||||
|
||||
render :all, status: :ok
|
||||
end
|
||||
|
||||
def favorites
|
||||
raise Api::V1::UnauthorizedError unless current_user
|
||||
|
||||
@per_page = 15
|
||||
|
||||
now = DateTime.current
|
||||
start_time =
|
||||
(
|
||||
now - params["recency"].to_i.seconds
|
||||
).to_datetime.beginning_of_day unless request.params["recency"].blank?
|
||||
|
||||
conditions = {}
|
||||
conditions[:element] = request.params["element"] unless request.params[
|
||||
"element"
|
||||
].blank?
|
||||
conditions[:raid] = request.params["raid"] unless request.params[
|
||||
"raid"
|
||||
].blank?
|
||||
conditions[:created_at] = start_time..now unless request.params[
|
||||
"recency"
|
||||
].blank?
|
||||
conditions[:favorites] = { user_id: current_user.id }
|
||||
|
||||
@parties =
|
||||
Party
|
||||
.joins(:favorites)
|
||||
.where(conditions)
|
||||
.order("favorites.created_at DESC")
|
||||
.paginate(page: request.params[:page], per_page: @per_page)
|
||||
.each { |party| party.favorited = party.is_favorited(current_user) }
|
||||
@count = Party.joins(:favorites).where(conditions).count
|
||||
|
||||
render :all, status: :ok
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @party.user != current_user
|
||||
render_unauthorized_response
|
||||
elsif @party.destroy
|
||||
render :destroyed, status: :ok
|
||||
end
|
||||
end
|
||||
|
||||
def weapons
|
||||
render_not_found_response if @party.nil?
|
||||
render :weapons, status: :ok
|
||||
end
|
||||
|
||||
def summons
|
||||
render_not_found_response if @party.nil?
|
||||
render :summons, status: :ok
|
||||
end
|
||||
|
||||
def characters
|
||||
render_not_found_response if @party.nil?
|
||||
render :characters, status: :ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def random_string
|
||||
numChars = 6
|
||||
o = [("a".."z"), ("A".."Z"), (0..9)].map(&:to_a).flatten
|
||||
return (0...numChars).map { o[rand(o.length)] }.join
|
||||
end
|
||||
|
||||
def set_from_slug
|
||||
@party = Party.where("shortcode = ?", params[:id]).first
|
||||
@party.favorited =
|
||||
current_user && @party ? @party.is_favorited(current_user) : false
|
||||
end
|
||||
|
||||
def set
|
||||
@party = Party.where("id = ?", params[:id]).first
|
||||
end
|
||||
|
||||
def party_params
|
||||
params.require(:party).permit(
|
||||
:user_id,
|
||||
:extra,
|
||||
:name,
|
||||
:description,
|
||||
:raid_id,
|
||||
:job_id,
|
||||
:skill0_id,
|
||||
:skill1_id,
|
||||
:skill2_id,
|
||||
:skill3_id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
class Api::V1::RaidsController < Api::V1::ApiController
|
||||
def all
|
||||
@raids = Raid.all()
|
||||
render :all, status: :ok
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class RaidsController < Api::V1::ApiController
|
||||
def all
|
||||
render json: RaidBlueprint.render(Raid.all)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,139 +1,194 @@
|
|||
class Api::V1::SearchController < Api::V1::ApiController
|
||||
def characters
|
||||
filters = search_params[:filters]
|
||||
locale = search_params[:locale] || 'en'
|
||||
conditions = {}
|
||||
# frozen_string_literal: true
|
||||
|
||||
if filters
|
||||
conditions[:rarity] = filters['rarity'] unless filters['rarity'].blank? || filters['rarity'].empty?
|
||||
conditions[:element] = filters['element'] unless filters['element'].blank? || filters['element'].empty?
|
||||
conditions[:proficiency1] = filters['proficiency1'] unless filters['proficiency1'].blank? || filters['proficiency1'].empty?
|
||||
conditions[:proficiency2] = filters['proficiency2'] unless filters['proficiency2'].blank? || filters['proficiency2'].empty?
|
||||
# conditions[:series] = filters['series'] unless filters['series'].blank? || filters['series'].empty?
|
||||
end
|
||||
module Api
|
||||
module V1
|
||||
PER_PAGE = 10
|
||||
|
||||
@characters = if search_params[:query].present? && search_params[:query].length >= 2
|
||||
class SearchController < Api::V1::ApiController
|
||||
def characters
|
||||
filters = search_params[:filters]
|
||||
locale = search_params[:locale] || 'en'
|
||||
conditions = {}
|
||||
|
||||
if filters
|
||||
conditions[:rarity] = filters['rarity'] unless filters['rarity'].blank? || filters['rarity'].empty?
|
||||
conditions[:element] = filters['element'] unless filters['element'].blank? || filters['element'].empty?
|
||||
unless filters['proficiency1'].blank? || filters['proficiency1'].empty?
|
||||
conditions[:proficiency1] =
|
||||
filters['proficiency1']
|
||||
end
|
||||
unless filters['proficiency2'].blank? || filters['proficiency2'].empty?
|
||||
conditions[:proficiency2] =
|
||||
filters['proficiency2']
|
||||
end
|
||||
# conditions[:series] = filters['series'] unless filters['series'].blank? || filters['series'].empty?
|
||||
end
|
||||
|
||||
characters = if search_params[:query].present? && search_params[:query].length >= 2
|
||||
if locale == 'ja'
|
||||
Character.jp_search(search_params[:query]).where(conditions)
|
||||
else
|
||||
Character.en_search(search_params[:query]).where(conditions)
|
||||
end
|
||||
else
|
||||
Character.where(conditions)
|
||||
end
|
||||
|
||||
count = characters.length
|
||||
paginated = characters.paginate(page: search_params[:page], per_page: PER_PAGE)
|
||||
|
||||
render json: CharacterBlueprint.render(paginated,
|
||||
root: :results,
|
||||
meta: {
|
||||
count: count,
|
||||
total_pages: total_pages(count),
|
||||
per_page: PER_PAGE
|
||||
})
|
||||
end
|
||||
|
||||
def weapons
|
||||
filters = search_params[:filters]
|
||||
locale = search_params[:locale] || 'en'
|
||||
conditions = {}
|
||||
|
||||
if filters
|
||||
conditions[:rarity] = filters['rarity'] unless filters['rarity'].blank? || filters['rarity'].empty?
|
||||
conditions[:element] = filters['element'] unless filters['element'].blank? || filters['element'].empty?
|
||||
unless filters['proficiency1'].blank? || filters['proficiency1'].empty?
|
||||
conditions[:proficiency] =
|
||||
filters['proficiency1']
|
||||
end
|
||||
conditions[:series] = filters['series'] unless filters['series'].blank? || filters['series'].empty?
|
||||
end
|
||||
|
||||
weapons = if search_params[:query].present? && search_params[:query].length >= 2
|
||||
if locale == 'ja'
|
||||
Character.jp_search(search_params[:query]).where(conditions)
|
||||
Weapon.jp_search(search_params[:query]).where(conditions)
|
||||
else
|
||||
Character.en_search(search_params[:query]).where(conditions)
|
||||
Weapon.en_search(search_params[:query]).where(conditions)
|
||||
end
|
||||
else
|
||||
Character.where(conditions)
|
||||
Weapon.where(conditions)
|
||||
end
|
||||
|
||||
@count = @characters.length
|
||||
@characters = @characters.paginate(page: search_params[:page], per_page: 10)
|
||||
end
|
||||
count = weapons.length
|
||||
paginated = weapons.paginate(page: search_params[:page], per_page: PER_PAGE)
|
||||
|
||||
def weapons
|
||||
filters = search_params[:filters]
|
||||
locale = search_params[:locale] || 'en'
|
||||
conditions = {}
|
||||
render json: WeaponBlueprint.render(paginated,
|
||||
root: :results,
|
||||
meta: {
|
||||
count: count,
|
||||
total_pages: total_pages(count),
|
||||
per_page: PER_PAGE
|
||||
})
|
||||
end
|
||||
|
||||
if filters
|
||||
conditions[:rarity] = filters['rarity'] unless filters['rarity'].blank? || filters['rarity'].empty?
|
||||
conditions[:element] = filters['element'] unless filters['element'].blank? || filters['element'].empty?
|
||||
conditions[:proficiency] = filters['proficiency1'] unless filters['proficiency1'].blank? || filters['proficiency1'].empty?
|
||||
conditions[:series] = filters['series'] unless filters['series'].blank? || filters['series'].empty?
|
||||
end
|
||||
def summons
|
||||
filters = search_params[:filters]
|
||||
locale = search_params[:locale] || 'en'
|
||||
conditions = {}
|
||||
|
||||
@weapons = if search_params[:query].present? && search_params[:query].length >= 2
|
||||
if locale == 'ja'
|
||||
Weapon.jp_search(search_params[:query]).where(conditions)
|
||||
if filters
|
||||
conditions[:rarity] = filters['rarity'] unless filters['rarity'].blank? || filters['rarity'].empty?
|
||||
conditions[:element] = filters['element'] unless filters['element'].blank? || filters['element'].empty?
|
||||
end
|
||||
|
||||
summons = if search_params[:query].present? && search_params[:query].length >= 2
|
||||
if locale == 'ja'
|
||||
Summon.jp_search(search_params[:query]).where(conditions)
|
||||
else
|
||||
Summon.en_search(search_params[:query]).where(conditions)
|
||||
end
|
||||
else
|
||||
Summon.where(conditions)
|
||||
end
|
||||
|
||||
count = summons.length
|
||||
paginated = summons.paginate(page: search_params[:page], per_page: PER_PAGE)
|
||||
|
||||
render json: SummonBlueprint.render(paginated,
|
||||
root: :results,
|
||||
meta: {
|
||||
count: count,
|
||||
total_pages: total_pages(count),
|
||||
per_page: PER_PAGE
|
||||
})
|
||||
end
|
||||
|
||||
def job_skills
|
||||
raise Api::V1::NoJobProvidedError unless search_params[:job].present?
|
||||
|
||||
# Set up basic parameters we'll use
|
||||
job = Job.find(search_params[:job])
|
||||
locale = search_params[:locale] || 'en'
|
||||
|
||||
# Set the conditions based on the group requested
|
||||
conditions = {}
|
||||
if search_params[:filters].present? && search_params[:filters]['group'].present?
|
||||
group = search_params[:filters]['group'].to_i
|
||||
|
||||
if group >= 0 && group < 4
|
||||
conditions[:color] = group
|
||||
conditions[:emp] = false
|
||||
conditions[:base] = false
|
||||
elsif group == 4
|
||||
conditions[:emp] = true
|
||||
elsif group == 5
|
||||
conditions[:base] = true
|
||||
end
|
||||
end
|
||||
|
||||
# Perform the query
|
||||
skills = if search_params[:query].present? && search_params[:query].length >= 2
|
||||
JobSkill.method("#{locale}_search").call(search_params[:query])
|
||||
.where(conditions)
|
||||
.where(job: job.id, main: false)
|
||||
.or(
|
||||
JobSkill.method("#{locale}_search").call(search_params[:query])
|
||||
.where(conditions)
|
||||
.where(sub: true)
|
||||
.where.not(job: job.id)
|
||||
)
|
||||
else
|
||||
Weapon.en_search(search_params[:query]).where(conditions)
|
||||
JobSkill.all
|
||||
.where(conditions)
|
||||
.where(job: job.id, main: false)
|
||||
.or(
|
||||
JobSkill.all
|
||||
.where(conditions)
|
||||
.where(sub: true)
|
||||
.where.not(job: job.id)
|
||||
)
|
||||
.or(
|
||||
JobSkill.all
|
||||
.where(conditions)
|
||||
.where(job: job.base_job.id, base: true)
|
||||
.where.not(job: job.id)
|
||||
)
|
||||
end
|
||||
else
|
||||
Weapon.where(conditions)
|
||||
end
|
||||
|
||||
@count = @weapons.length
|
||||
@weapons = @weapons.paginate(page: search_params[:page], per_page: 10)
|
||||
end
|
||||
count = skills.length
|
||||
paginated = skills.paginate(page: search_params[:page], per_page: PER_PAGE)
|
||||
|
||||
def summons
|
||||
filters = search_params[:filters]
|
||||
locale = search_params[:locale] || 'en'
|
||||
conditions = {}
|
||||
render json: JobSkillBlueprint.render(paginated,
|
||||
root: :results,
|
||||
meta: {
|
||||
count: count,
|
||||
total_pages: total_pages(count),
|
||||
per_page: PER_PAGE
|
||||
})
|
||||
end
|
||||
|
||||
if filters
|
||||
conditions[:rarity] = filters['rarity'] unless filters['rarity'].blank? || filters['rarity'].empty?
|
||||
conditions[:element] = filters['element'] unless filters['element'].blank? || filters['element'].empty?
|
||||
end
|
||||
private
|
||||
|
||||
@summons = if search_params[:query].present? && search_params[:query].length >= 2
|
||||
if locale == 'ja'
|
||||
Summon.jp_search(search_params[:query]).where(conditions)
|
||||
else
|
||||
Summon.en_search(search_params[:query]).where(conditions)
|
||||
end
|
||||
else
|
||||
Summon.where(conditions)
|
||||
end
|
||||
def total_pages(count)
|
||||
count.to_f / PER_PAGE > 1 ? (count.to_f / PER_PAGE).ceil : 1
|
||||
end
|
||||
|
||||
@count = @summons.length
|
||||
@summons = @summons.paginate(page: search_params[:page], per_page: 10)
|
||||
end
|
||||
|
||||
def job_skills
|
||||
raise Api::V1::NoJobProvidedError unless search_params[:job].present?
|
||||
|
||||
# Set up basic parameters we'll use
|
||||
job = Job.find(search_params[:job])
|
||||
locale = search_params[:locale] || 'en'
|
||||
|
||||
# Set the conditions based on the group requested
|
||||
conditions = {}
|
||||
if search_params[:filters].present? && search_params[:filters]['group'].present?
|
||||
group = search_params[:filters]['group'].to_i
|
||||
|
||||
if group >= 0 && group < 4
|
||||
conditions[:color] = group
|
||||
conditions[:emp] = false
|
||||
conditions[:base] = false
|
||||
elsif group == 4
|
||||
conditions[:emp] = true
|
||||
elsif group == 5
|
||||
conditions[:base] = true
|
||||
# Specify whitelisted properties that can be modified.
|
||||
def search_params
|
||||
params.require(:search).permit!
|
||||
end
|
||||
end
|
||||
|
||||
# Perform the query
|
||||
@skills = if search_params[:query].present? && search_params[:query].length >= 2
|
||||
JobSkill.method("#{locale}_search").call(search_params[:query])
|
||||
.where(conditions)
|
||||
.where(job: job.id, main: false)
|
||||
.or(
|
||||
JobSkill.method("#{locale}_search").call(search_params[:query])
|
||||
.where(conditions)
|
||||
.where(sub: true)
|
||||
)
|
||||
else
|
||||
JobSkill.all
|
||||
.where(conditions)
|
||||
.where(job: job.id, main: false)
|
||||
.or(
|
||||
JobSkill.all
|
||||
.where(conditions)
|
||||
.where(sub: true)
|
||||
)
|
||||
.or(
|
||||
JobSkill.all
|
||||
.where(conditions)
|
||||
.where(job: job.base_job.id, base: true)
|
||||
.where.not(job: job.id)
|
||||
)
|
||||
end
|
||||
|
||||
@count = @skills.length
|
||||
@skills = @skills.paginate(page: search_params[:page], per_page: 10)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Specify whitelisted properties that can be modified.
|
||||
def search_params
|
||||
params.require(:search).permit!
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,103 +1,113 @@
|
|||
class Api::V1::UsersController < Api::V1::ApiController
|
||||
class ForbiddenError < StandardError; end
|
||||
# frozen_string_literal: true
|
||||
|
||||
before_action :set, except: ['create', 'check_email', 'check_username']
|
||||
before_action :set_by_id, only: ['info', 'update']
|
||||
module Api
|
||||
module V1
|
||||
PER_PAGE = 15
|
||||
|
||||
def create
|
||||
@user = User.new(user_params)
|
||||
class UsersController < Api::V1::ApiController
|
||||
class ForbiddenError < StandardError; end
|
||||
|
||||
token = Doorkeeper::AccessToken.create!(
|
||||
before_action :set, except: %w[create check_email check_username]
|
||||
before_action :set_by_id, only: %w[info update]
|
||||
|
||||
def create
|
||||
user = User.new(user_params)
|
||||
|
||||
if user.save!
|
||||
token = Doorkeeper::AccessToken.create!(
|
||||
application_id: nil,
|
||||
resource_owner_id: @user.id,
|
||||
resource_owner_id: user.id,
|
||||
expires_in: 30.days,
|
||||
scopes: 'public'
|
||||
).token
|
||||
).token
|
||||
|
||||
if @user.save!
|
||||
@presenter = {
|
||||
user_id: @user.id,
|
||||
username: @user.username,
|
||||
token: token
|
||||
}
|
||||
|
||||
render :create, status: :created
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def update
|
||||
render :info, status: :ok if @user.update(user_params)
|
||||
end
|
||||
|
||||
def info
|
||||
render :info, status: :ok
|
||||
end
|
||||
|
||||
def show
|
||||
if @user
|
||||
@per_page = 15
|
||||
|
||||
now = DateTime.current
|
||||
start_time = (now - params['recency'].to_i.seconds).to_datetime.beginning_of_day unless request.params['recency'].blank?
|
||||
|
||||
conditions = {}
|
||||
conditions[:element] = request.params['element'] unless request.params['element'].blank?
|
||||
conditions[:raid] = request.params['raid'] unless request.params['raid'].blank?
|
||||
conditions[:created_at] = start_time..now unless request.params['recency'].blank?
|
||||
conditions[:user_id] = @user.id
|
||||
|
||||
@parties = Party
|
||||
.where(conditions)
|
||||
.order(created_at: :desc)
|
||||
.paginate(page: request.params[:page], per_page: @per_page)
|
||||
.each { |party|
|
||||
party.favorited = (current_user) ? party.is_favorited(current_user) : false
|
||||
}
|
||||
@count = Party.where(conditions).count
|
||||
else
|
||||
render_not_found_response
|
||||
end
|
||||
end
|
||||
|
||||
def check_email
|
||||
if params[:email].present?
|
||||
@available = User.where("email = ?", params[:email]).count == 0
|
||||
else
|
||||
@available = false
|
||||
return render json: UserBlueprint.render({
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
token: token
|
||||
},
|
||||
view: :token),
|
||||
status: :created
|
||||
end
|
||||
|
||||
render :available
|
||||
end
|
||||
render_validation_error_response(@user)
|
||||
end
|
||||
|
||||
def check_username
|
||||
if params[:username].present?
|
||||
@available = User.where("username = ?", params[:username]).count == 0
|
||||
else
|
||||
@available = false
|
||||
def update
|
||||
render json: UserBlueprint.render(@user, view: :minimal) if @user.update(user_params)
|
||||
end
|
||||
|
||||
def info
|
||||
render json: UserBlueprint.render(@user, view: :minimal)
|
||||
end
|
||||
|
||||
def show
|
||||
render_not_found_response('user') unless @user
|
||||
|
||||
conditions = build_conditions(request.params)
|
||||
conditions[:user_id] = @user.id
|
||||
|
||||
parties = Party
|
||||
.where(conditions)
|
||||
.order(created_at: :desc)
|
||||
.paginate(page: request.params[:page], per_page: PER_PAGE)
|
||||
.each do |party|
|
||||
party.favorited = current_user ? party.is_favorited(current_user) : false
|
||||
end
|
||||
|
||||
render :available
|
||||
end
|
||||
count = Party.where(conditions).count
|
||||
|
||||
def destroy
|
||||
end
|
||||
render json: UserBlueprint.render(@user,
|
||||
view: :profile,
|
||||
root: 'profile',
|
||||
parties: parties,
|
||||
meta: {
|
||||
count: count,
|
||||
total_pages: count.to_f / PER_PAGE > 1 ? (count.to_f / PER_PAGE).ceil : 1,
|
||||
per_page: PER_PAGE
|
||||
})
|
||||
end
|
||||
|
||||
private
|
||||
def check_email
|
||||
render json: EmptyBlueprint.render_as_json(nil, email: params[:email], availability: true)
|
||||
end
|
||||
|
||||
# Specify whitelisted properties that can be modified.
|
||||
def set
|
||||
@user = User.where("username = ?", params[:id]).first
|
||||
end
|
||||
def check_username
|
||||
render json: EmptyBlueprint.render_as_json(nil, username: params[:username], availability: true)
|
||||
end
|
||||
|
||||
def set_by_id
|
||||
@user = User.where("id = ?", params[:id]).first
|
||||
end
|
||||
def destroy; end
|
||||
|
||||
def user_params
|
||||
private
|
||||
|
||||
def build_conditions(params)
|
||||
unless params['recency'].blank?
|
||||
start_time = (DateTime.current - params['recency'].to_i.seconds)
|
||||
.to_datetime.beginning_of_day
|
||||
end
|
||||
|
||||
{}.tap do |hash|
|
||||
hash[:element] = params['element'] unless params['element'].blank?
|
||||
hash[:raid] = params['raid'] unless params['raid'].blank?
|
||||
hash[:created_at] = start_time..DateTime.current unless params['recency'].blank?
|
||||
end
|
||||
end
|
||||
|
||||
# Specify whitelisted properties that can be modified.
|
||||
def set
|
||||
@user = User.where('username = ?', params[:id]).first
|
||||
end
|
||||
|
||||
def set_by_id
|
||||
@user = User.where('id = ?', params[:id]).first
|
||||
end
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(
|
||||
:username, :email, :password, :password_confirmation,
|
||||
:granblue_id, :picture, :element, :language, :gender, :private
|
||||
:username, :email, :password, :password_confirmation,
|
||||
:granblue_id, :picture, :element, :language, :gender, :private
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,11 +1,19 @@
|
|||
class Api::V1::WeaponKeysController < Api::V1::ApiController
|
||||
def all
|
||||
conditions = {}
|
||||
conditions[:series] = request.params['series']
|
||||
conditions[:slot] = request.params['slot']
|
||||
conditions[:group] = request.params['group'] unless request.params['group'].blank?
|
||||
# frozen_string_literal: true
|
||||
|
||||
@keys = WeaponKey.where(conditions)
|
||||
render :all, status: :ok
|
||||
module Api
|
||||
module V1
|
||||
class WeaponKeysController < Api::V1::ApiController
|
||||
def all
|
||||
conditions = {}.tap do |hash|
|
||||
hash[:series] = request.params['series']
|
||||
hash[:slot] = request.params['slot']
|
||||
hash[:group] = request.params['group'] unless request.params['group'].blank?
|
||||
end
|
||||
|
||||
render json: WeaponKeyBlueprint.render(
|
||||
WeaponKey.where(conditions)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ApplicationController < ActionController::API
|
||||
# Not usually required for Rails 5 in API mode, but
|
||||
# necessary here because we're using RABL.
|
||||
include ActionView::Rendering
|
||||
append_view_path "#{Rails.root}/app/views"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,36 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class TokensController < Doorkeeper::TokensController
|
||||
# Overriding create action
|
||||
# POST /oauth/token
|
||||
def create
|
||||
response = strategy.authorize
|
||||
body = response.body
|
||||
# Overriding create action
|
||||
# POST /oauth/token
|
||||
def create
|
||||
response = strategy.authorize
|
||||
body = response.body
|
||||
|
||||
if response.status == :ok
|
||||
# User the resource_owner_id from token to identify the user
|
||||
user = User.find(response.token.resource_owner_id) rescue nil
|
||||
if response.status == :ok
|
||||
# User the resource_owner_id from token to identify the user
|
||||
user = begin
|
||||
User.find(response.token.resource_owner_id)
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
|
||||
unless user.nil?
|
||||
### If you want to render user with template
|
||||
### create an ActionController to render out the user
|
||||
# ac = ActionController::Base.new()
|
||||
# user_json = ac.render_to_string( template: 'api/users/me', locals: { user: user})
|
||||
# body[:user] = Oj.load(user_json)
|
||||
unless user.nil?
|
||||
### If you want to render user with template
|
||||
### create an ActionController to render out the user
|
||||
# ac = ActionController::Base.new()
|
||||
# user_json = ac.render_to_string( template: 'api/users/me', locals: { user: user})
|
||||
# body[:user] = Oj.load(user_json)
|
||||
|
||||
### Or if you want to just append user using 'as_json'
|
||||
body[:user] = {
|
||||
id: user.id,
|
||||
username: user.username
|
||||
}
|
||||
### Or if you want to just append user using 'as_json'
|
||||
body[:user] = {
|
||||
id: user.id,
|
||||
username: user.username
|
||||
}
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
self.headers.merge! response.headers
|
||||
self.response_body = body.to_json
|
||||
self.status = response.status
|
||||
|
||||
rescue Doorkeeper::Errors::DoorkeeperError => e
|
||||
handle_token_exception e
|
||||
end
|
||||
end
|
||||
|
||||
headers.merge! response.headers
|
||||
self.response_body = body.to_json
|
||||
self.status = response.status
|
||||
rescue Doorkeeper::Errors::DoorkeeperError => e
|
||||
handle_token_exception e
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
module Api::V1
|
||||
class FavoriteAlreadyExistsError < GranblueError
|
||||
def http_status
|
||||
422
|
||||
end
|
||||
|
||||
def code
|
||||
"favorite_already_exists"
|
||||
end
|
||||
|
||||
def message
|
||||
"This user has favorited this party already"
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{
|
||||
message: message,
|
||||
code: code
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
module Api::V1
|
||||
class IncompatibleSkillError < GranblueError
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
|
||||
def http_status
|
||||
422
|
||||
end
|
||||
|
||||
def code
|
||||
'incompatible_skill'
|
||||
end
|
||||
|
||||
def message
|
||||
'The selected skill cannot be added to the current job'
|
||||
end
|
||||
|
||||
def to_hash
|
||||
ap @data
|
||||
{
|
||||
message: message,
|
||||
code: code,
|
||||
job: @data[:job],
|
||||
skill: @data[:skill]
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
module Api::V1
|
||||
class NoJobProvidedError < GranblueError
|
||||
def http_status
|
||||
422
|
||||
end
|
||||
|
||||
def code
|
||||
"no_job_provided"
|
||||
end
|
||||
|
||||
def message
|
||||
"A job ID must be provided"
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{
|
||||
message: message,
|
||||
code: code
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
module Api::V1
|
||||
class NoJobSkillProvidedError < GranblueError
|
||||
def http_status
|
||||
422
|
||||
end
|
||||
|
||||
def code
|
||||
"no_job_skill_provided"
|
||||
end
|
||||
|
||||
def message
|
||||
"A job skill ID must be provided"
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{
|
||||
message: message,
|
||||
code: code
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
module Api::V1
|
||||
class UnauthorizedError < StandardError
|
||||
def http_status
|
||||
401
|
||||
end
|
||||
|
||||
def code
|
||||
"unauthorized"
|
||||
end
|
||||
|
||||
def message
|
||||
"User is not allowed to modify that resource"
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{
|
||||
message: message,
|
||||
code: code
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
26
app/errors/api/v1/favorite_already_exists_error.rb
Normal file
26
app/errors/api/v1/favorite_already_exists_error.rb
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class FavoriteAlreadyExistsError < GranblueError
|
||||
def http_status
|
||||
422
|
||||
end
|
||||
|
||||
def code
|
||||
'favorite_already_exists'
|
||||
end
|
||||
|
||||
def message
|
||||
'This user has favorited this party already'
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{
|
||||
message: message,
|
||||
code: code
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -4,7 +4,7 @@ module Api
|
|||
module V1
|
||||
# This is the base error that we inherit from for application errors
|
||||
class GranblueError < StandardError
|
||||
def initialize(data)
|
||||
def initialize(data = '')
|
||||
@data = data
|
||||
end
|
||||
|
||||
33
app/errors/api/v1/incompatible_skill_error.rb
Normal file
33
app/errors/api/v1/incompatible_skill_error.rb
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class IncompatibleSkillError < GranblueError
|
||||
def initialize(data)
|
||||
@data = data
|
||||
end
|
||||
|
||||
def http_status
|
||||
422
|
||||
end
|
||||
|
||||
def code
|
||||
'incompatible_skill'
|
||||
end
|
||||
|
||||
def message
|
||||
'The selected skill cannot be added to the current job'
|
||||
end
|
||||
|
||||
def to_hash
|
||||
ap @data
|
||||
{
|
||||
message: message,
|
||||
code: code,
|
||||
job: @data[:job],
|
||||
skill: @data[:skill]
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
26
app/errors/api/v1/no_job_provided_error.rb
Normal file
26
app/errors/api/v1/no_job_provided_error.rb
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class NoJobProvidedError < GranblueError
|
||||
def http_status
|
||||
422
|
||||
end
|
||||
|
||||
def code
|
||||
'no_job_provided'
|
||||
end
|
||||
|
||||
def message
|
||||
'A job ID must be provided'
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{
|
||||
message: message,
|
||||
code: code
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
26
app/errors/api/v1/no_job_skill_provided_error.rb
Normal file
26
app/errors/api/v1/no_job_skill_provided_error.rb
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class NoJobSkillProvidedError < GranblueError
|
||||
def http_status
|
||||
422
|
||||
end
|
||||
|
||||
def code
|
||||
'no_job_skill_provided'
|
||||
end
|
||||
|
||||
def message
|
||||
'A job skill ID must be provided'
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{
|
||||
message: message,
|
||||
code: code
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class SameFavoriteUserError < GranblueError
|
||||
26
app/errors/api/v1/unauthorized_error.rb
Normal file
26
app/errors/api/v1/unauthorized_error.rb
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class UnauthorizedError < StandardError
|
||||
def http_status
|
||||
401
|
||||
end
|
||||
|
||||
def code
|
||||
'unauthorized'
|
||||
end
|
||||
|
||||
def message
|
||||
'User is not allowed to modify that resource'
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{
|
||||
message: message,
|
||||
code: code
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,33 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ValidationErrorSerializer
|
||||
def initialize(record, field, details)
|
||||
@record = record
|
||||
@field = field
|
||||
@details = details
|
||||
end
|
||||
def initialize(record, field, details)
|
||||
@record = record
|
||||
@field = field
|
||||
@details = details
|
||||
end
|
||||
|
||||
def serialize
|
||||
{
|
||||
resource: resource,
|
||||
field: field,
|
||||
code: code
|
||||
}
|
||||
end
|
||||
def serialize
|
||||
{
|
||||
resource: resource,
|
||||
field: field,
|
||||
code: code
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def resource
|
||||
@record.class.to_s
|
||||
end
|
||||
def resource
|
||||
@record.class.to_s
|
||||
end
|
||||
|
||||
def field
|
||||
@field.to_s
|
||||
end
|
||||
def field
|
||||
@field.to_s
|
||||
end
|
||||
|
||||
def code
|
||||
@details[:error].to_s
|
||||
end
|
||||
def code
|
||||
@details[:error].to_s
|
||||
end
|
||||
|
||||
def underscored_resource_name
|
||||
@record.class.to_s.gsub('::', '').underscore
|
||||
end
|
||||
end
|
||||
def underscored_resource_name
|
||||
@record.class.to_s.gsub('::', '').underscore
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ValidationErrorsSerializer
|
||||
attr_reader :record
|
||||
attr_reader :record
|
||||
|
||||
def initialize(record)
|
||||
@record = record
|
||||
end
|
||||
def initialize(record)
|
||||
@record = record
|
||||
end
|
||||
|
||||
def serialize
|
||||
record.errors.details.map do |field, details|
|
||||
details.map do |error_details|
|
||||
ValidationErrorSerializer.new(record, field, error_details).serialize
|
||||
end
|
||||
end.flatten
|
||||
end
|
||||
end
|
||||
def serialize
|
||||
record.errors.details.map do |field, details|
|
||||
details.map do |error_details|
|
||||
ValidationErrorSerializer.new(record, field, error_details).serialize
|
||||
end
|
||||
end.flatten
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ApplicationRecord < ActiveRecord::Base
|
||||
self.abstract_class = true
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,94 +1,99 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Character < ApplicationRecord
|
||||
include PgSearch::Model
|
||||
include PgSearch::Model
|
||||
|
||||
pg_search_scope :en_search,
|
||||
against: :name_en,
|
||||
using: {
|
||||
trigram: {
|
||||
threshold: 0.18
|
||||
}
|
||||
}
|
||||
pg_search_scope :en_search,
|
||||
against: :name_en,
|
||||
using: {
|
||||
trigram: {
|
||||
threshold: 0.18
|
||||
}
|
||||
}
|
||||
|
||||
pg_search_scope :jp_search,
|
||||
against: :name_jp,
|
||||
using: {
|
||||
tsearch: {
|
||||
prefix: true,
|
||||
dictionary: "simple"
|
||||
}
|
||||
}
|
||||
pg_search_scope :jp_search,
|
||||
against: :name_jp,
|
||||
using: {
|
||||
tsearch: {
|
||||
prefix: true,
|
||||
dictionary: 'simple'
|
||||
}
|
||||
}
|
||||
|
||||
def display_resource(character)
|
||||
character.name_en
|
||||
end
|
||||
def blueprint
|
||||
CharacterBlueprint
|
||||
end
|
||||
|
||||
# enum rarities: {
|
||||
# R: 1,
|
||||
# SR: 2,
|
||||
# SSR: 3
|
||||
# }
|
||||
def display_resource(character)
|
||||
character.name_en
|
||||
end
|
||||
|
||||
# enum elements: {
|
||||
# Null: 0,
|
||||
# Wind: 1,
|
||||
# Fire: 2,
|
||||
# Water: 3,
|
||||
# Earth: 4,
|
||||
# Dark: 5,
|
||||
# Light: 6
|
||||
# }
|
||||
# enum rarities: {
|
||||
# R: 1,
|
||||
# SR: 2,
|
||||
# SSR: 3
|
||||
# }
|
||||
|
||||
# enum proficiency1s: {
|
||||
# Sabre: 1,
|
||||
# Dagger: 2,
|
||||
# Axe: 3,
|
||||
# Spear: 4,
|
||||
# Bow: 5,
|
||||
# Staff: 6,
|
||||
# Melee: 7,
|
||||
# Harp: 8,
|
||||
# Gun: 9,
|
||||
# Katana: 10
|
||||
# }, _prefix: "proficiency1"
|
||||
# enum elements: {
|
||||
# Null: 0,
|
||||
# Wind: 1,
|
||||
# Fire: 2,
|
||||
# Water: 3,
|
||||
# Earth: 4,
|
||||
# Dark: 5,
|
||||
# Light: 6
|
||||
# }
|
||||
|
||||
# enum proficiency2s: {
|
||||
# None: 0,
|
||||
# Sabre: 1,
|
||||
# Dagger: 2,
|
||||
# Axe: 3,
|
||||
# Spear: 4,
|
||||
# Bow: 5,
|
||||
# Staff: 6,
|
||||
# Melee: 7,
|
||||
# Harp: 8,
|
||||
# Gun: 9,
|
||||
# Katana: 10,
|
||||
# }, _default: :None, _prefix: "proficiency2"
|
||||
# enum proficiency1s: {
|
||||
# Sabre: 1,
|
||||
# Dagger: 2,
|
||||
# Axe: 3,
|
||||
# Spear: 4,
|
||||
# Bow: 5,
|
||||
# Staff: 6,
|
||||
# Melee: 7,
|
||||
# Harp: 8,
|
||||
# Gun: 9,
|
||||
# Katana: 10
|
||||
# }, _prefix: "proficiency1"
|
||||
|
||||
# enum race1s: {
|
||||
# Unknown: 0,
|
||||
# Human: 1,
|
||||
# Erune: 2,
|
||||
# Draph: 3,
|
||||
# Harvin: 4,
|
||||
# Primal: 5
|
||||
# }, _prefix: "race1"
|
||||
# enum proficiency2s: {
|
||||
# None: 0,
|
||||
# Sabre: 1,
|
||||
# Dagger: 2,
|
||||
# Axe: 3,
|
||||
# Spear: 4,
|
||||
# Bow: 5,
|
||||
# Staff: 6,
|
||||
# Melee: 7,
|
||||
# Harp: 8,
|
||||
# Gun: 9,
|
||||
# Katana: 10,
|
||||
# }, _default: :None, _prefix: "proficiency2"
|
||||
|
||||
# enum race2s: {
|
||||
# Unknown: 0,
|
||||
# Human: 1,
|
||||
# Erune: 2,
|
||||
# Draph: 3,
|
||||
# Harvin: 4,
|
||||
# Primal: 5,
|
||||
# None: 6
|
||||
# }, _default: :None, _prefix: "race2"
|
||||
# enum race1s: {
|
||||
# Unknown: 0,
|
||||
# Human: 1,
|
||||
# Erune: 2,
|
||||
# Draph: 3,
|
||||
# Harvin: 4,
|
||||
# Primal: 5
|
||||
# }, _prefix: "race1"
|
||||
|
||||
# enum gender: {
|
||||
# Unknown: 0,
|
||||
# Male: 1,
|
||||
# Female: 2,
|
||||
# "Male/Female": 3
|
||||
# }
|
||||
# enum race2s: {
|
||||
# Unknown: 0,
|
||||
# Human: 1,
|
||||
# Erune: 2,
|
||||
# Draph: 3,
|
||||
# Harvin: 4,
|
||||
# Primal: 5,
|
||||
# None: 6
|
||||
# }, _default: :None, _prefix: "race2"
|
||||
|
||||
# enum gender: {
|
||||
# Unknown: 0,
|
||||
# Male: 1,
|
||||
# Female: 2,
|
||||
# "Male/Female": 3
|
||||
# }
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
class Favorite < ApplicationRecord
|
||||
belongs_to :user
|
||||
belongs_to :party
|
||||
# frozen_string_literal: true
|
||||
|
||||
def party
|
||||
Party.find(self.party_id)
|
||||
end
|
||||
class Favorite < ApplicationRecord
|
||||
belongs_to :user
|
||||
belongs_to :party
|
||||
|
||||
def party
|
||||
Party.find(party_id)
|
||||
end
|
||||
|
||||
def favorite
|
||||
FavoriteBlueprint
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
class GridCharacter < ApplicationRecord
|
||||
belongs_to :party
|
||||
# frozen_string_literal: true
|
||||
|
||||
def character
|
||||
Character.find(self.character_id)
|
||||
end
|
||||
class GridCharacter < ApplicationRecord
|
||||
belongs_to :party
|
||||
|
||||
def character
|
||||
Character.find(character_id)
|
||||
end
|
||||
|
||||
def blueprint
|
||||
GridCharacterBlueprint
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
class GridSummon < ApplicationRecord
|
||||
belongs_to :party
|
||||
# frozen_string_literal: true
|
||||
|
||||
def summon
|
||||
Summon.find(self.summon_id)
|
||||
end
|
||||
class GridSummon < ApplicationRecord
|
||||
belongs_to :party
|
||||
|
||||
def summon
|
||||
Summon.find(summon_id)
|
||||
end
|
||||
|
||||
def blueprint
|
||||
GridSummonBlueprint
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,21 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class GridWeapon < ApplicationRecord
|
||||
belongs_to :party,
|
||||
counter_cache: :weapons_count
|
||||
belongs_to :party,
|
||||
counter_cache: :weapons_count
|
||||
|
||||
belongs_to :weapon_key1, class_name: 'WeaponKey', foreign_key: :weapon_key1_id, optional: true
|
||||
belongs_to :weapon_key2, class_name: 'WeaponKey', foreign_key: :weapon_key2_id, optional: true
|
||||
belongs_to :weapon_key3, class_name: 'WeaponKey', foreign_key: :weapon_key3_id, optional: true
|
||||
belongs_to :weapon_key1, class_name: 'WeaponKey', foreign_key: :weapon_key1_id, optional: true
|
||||
belongs_to :weapon_key2, class_name: 'WeaponKey', foreign_key: :weapon_key2_id, optional: true
|
||||
belongs_to :weapon_key3, class_name: 'WeaponKey', foreign_key: :weapon_key3_id, optional: true
|
||||
|
||||
def weapon
|
||||
Weapon.find(self.weapon_id)
|
||||
end
|
||||
def weapon
|
||||
Weapon.find(weapon_id)
|
||||
end
|
||||
|
||||
def weapon_keys
|
||||
weapon_keys = []
|
||||
weapon_keys.push(self.weapon_key1) if self.weapon_key1 != nil
|
||||
weapon_keys.push(self.weapon_key2) if self.weapon_key2 != nil
|
||||
weapon_keys.push(self.weapon_key3) if self.weapon_key3 != nil
|
||||
def weapon_keys
|
||||
weapon_keys = []
|
||||
weapon_keys.push(weapon_key1) unless weapon_key1.nil?
|
||||
weapon_keys.push(weapon_key2) unless weapon_key2.nil?
|
||||
weapon_keys.push(weapon_key3) unless weapon_key3.nil?
|
||||
|
||||
weapon_keys
|
||||
end
|
||||
weapon_keys
|
||||
end
|
||||
|
||||
def blueprint
|
||||
GridWeaponBlueprint
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Job < ApplicationRecord
|
||||
belongs_to :party
|
||||
|
||||
|
|
@ -6,6 +8,10 @@ class Job < ApplicationRecord
|
|||
class_name: 'Job',
|
||||
optional: true
|
||||
|
||||
def blueprint
|
||||
JobBlueprint
|
||||
end
|
||||
|
||||
def display_resource(job)
|
||||
job.name_en
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class JobSkill < ApplicationRecord
|
||||
alias eql? ==
|
||||
|
||||
|
|
@ -10,8 +12,8 @@ class JobSkill < ApplicationRecord
|
|||
using: {
|
||||
tsearch: {
|
||||
prefix: true,
|
||||
dictionary: "simple",
|
||||
},
|
||||
dictionary: 'simple'
|
||||
}
|
||||
}
|
||||
|
||||
pg_search_scope :jp_search,
|
||||
|
|
@ -19,15 +21,19 @@ class JobSkill < ApplicationRecord
|
|||
using: {
|
||||
tsearch: {
|
||||
prefix: true,
|
||||
dictionary: "simple",
|
||||
},
|
||||
dictionary: 'simple'
|
||||
}
|
||||
}
|
||||
|
||||
def blueprint
|
||||
JobSkillBlueprint
|
||||
end
|
||||
|
||||
def display_resource(skill)
|
||||
skill.name_en
|
||||
end
|
||||
|
||||
def ==(o)
|
||||
self.class == o.class && id == o.id
|
||||
def ==(other)
|
||||
self.class == other.class && id == other.id
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Party < ApplicationRecord
|
||||
##### ActiveRecord Associations
|
||||
belongs_to :user, optional: true
|
||||
|
|
@ -5,38 +7,38 @@ class Party < ApplicationRecord
|
|||
belongs_to :job, optional: true
|
||||
|
||||
belongs_to :skill0,
|
||||
foreign_key: "skill0_id",
|
||||
class_name: "JobSkill",
|
||||
foreign_key: 'skill0_id',
|
||||
class_name: 'JobSkill',
|
||||
optional: true
|
||||
|
||||
belongs_to :skill1,
|
||||
foreign_key: "skill1_id",
|
||||
class_name: "JobSkill",
|
||||
foreign_key: 'skill1_id',
|
||||
class_name: 'JobSkill',
|
||||
optional: true
|
||||
|
||||
belongs_to :skill2,
|
||||
foreign_key: "skill2_id",
|
||||
class_name: "JobSkill",
|
||||
foreign_key: 'skill2_id',
|
||||
class_name: 'JobSkill',
|
||||
optional: true
|
||||
|
||||
belongs_to :skill3,
|
||||
foreign_key: "skill3_id",
|
||||
class_name: "JobSkill",
|
||||
foreign_key: 'skill3_id',
|
||||
class_name: 'JobSkill',
|
||||
optional: true
|
||||
|
||||
has_many :characters,
|
||||
foreign_key: "party_id",
|
||||
class_name: "GridCharacter",
|
||||
foreign_key: 'party_id',
|
||||
class_name: 'GridCharacter',
|
||||
dependent: :destroy
|
||||
|
||||
has_many :weapons,
|
||||
foreign_key: "party_id",
|
||||
class_name: "GridWeapon",
|
||||
foreign_key: 'party_id',
|
||||
class_name: 'GridWeapon',
|
||||
dependent: :destroy
|
||||
|
||||
has_many :summons,
|
||||
foreign_key: "party_id",
|
||||
class_name: "GridSummon",
|
||||
foreign_key: 'party_id',
|
||||
class_name: 'GridSummon',
|
||||
dependent: :destroy
|
||||
|
||||
has_many :favorites
|
||||
|
|
@ -50,23 +52,23 @@ class Party < ApplicationRecord
|
|||
user.favorite_parties.include? self
|
||||
end
|
||||
|
||||
def blueprint
|
||||
PartyBlueprint
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def skills_are_unique
|
||||
skills = [skill0, skill1, skill2, skill3].compact
|
||||
|
||||
if skills.uniq.length != skills.length
|
||||
errors.add(:skill1, "must be unique") if skill0 == skill1
|
||||
return unless skills.uniq.length != skills.length
|
||||
|
||||
if skill0 == skill2 || skill1 == skill2
|
||||
errors.add(:skill2, "must be unique")
|
||||
end
|
||||
errors.add(:skill1, 'must be unique') if skill0 == skill1
|
||||
|
||||
if skill0 == skill3 || skill1 == skill3 || skill2 == skill3
|
||||
errors.add(:skill3, "must be unique")
|
||||
end
|
||||
errors.add(:skill2, 'must be unique') if skill0 == skill2 || skill1 == skill2
|
||||
|
||||
errors.add(:job_skills, "must be unique")
|
||||
end
|
||||
errors.add(:skill3, 'must be unique') if skill0 == skill3 || skill1 == skill3 || skill2 == skill3
|
||||
|
||||
errors.add(:job_skills, 'must be unique')
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,2 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Raid < ApplicationRecord
|
||||
def blueprint
|
||||
RaidBlueprint
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,24 +1,30 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Summon < ApplicationRecord
|
||||
include PgSearch::Model
|
||||
include PgSearch::Model
|
||||
|
||||
pg_search_scope :en_search,
|
||||
against: :name_en,
|
||||
using: {
|
||||
trigram: {
|
||||
threshold: 0.18
|
||||
}
|
||||
}
|
||||
pg_search_scope :en_search,
|
||||
against: :name_en,
|
||||
using: {
|
||||
trigram: {
|
||||
threshold: 0.18
|
||||
}
|
||||
}
|
||||
|
||||
pg_search_scope :jp_search,
|
||||
against: :name_jp,
|
||||
using: {
|
||||
tsearch: {
|
||||
prefix: true,
|
||||
dictionary: "simple"
|
||||
}
|
||||
}
|
||||
pg_search_scope :jp_search,
|
||||
against: :name_jp,
|
||||
using: {
|
||||
tsearch: {
|
||||
prefix: true,
|
||||
dictionary: 'simple'
|
||||
}
|
||||
}
|
||||
|
||||
def display_resource(summon)
|
||||
summon.name_en
|
||||
end
|
||||
def blueprint
|
||||
SummonBlueprint
|
||||
end
|
||||
|
||||
def display_resource(summon)
|
||||
summon.name_en
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,43 +1,49 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class User < ApplicationRecord
|
||||
before_save { self.email = email.downcase }
|
||||
before_save { self.email = email.downcase }
|
||||
|
||||
##### ActiveRecord Associations
|
||||
has_many :parties, dependent: :destroy
|
||||
has_many :favorites, dependent: :destroy
|
||||
##### ActiveRecord Associations
|
||||
has_many :parties, dependent: :destroy
|
||||
has_many :favorites, dependent: :destroy
|
||||
|
||||
##### ActiveRecord Validations
|
||||
validates :username,
|
||||
presence: true,
|
||||
length: { minimum: 3, maximum: 26 }
|
||||
##### ActiveRecord Validations
|
||||
validates :username,
|
||||
presence: true,
|
||||
length: { minimum: 3, maximum: 26 }
|
||||
|
||||
validates :email,
|
||||
presence: true,
|
||||
uniqueness: true,
|
||||
email: true
|
||||
|
||||
validates :password,
|
||||
length: { minimum: 8 },
|
||||
presence: true,
|
||||
on: :create
|
||||
validates :email,
|
||||
presence: true,
|
||||
uniqueness: true,
|
||||
email: true
|
||||
|
||||
validates :password,
|
||||
length: { minimum: 8 },
|
||||
on: :update,
|
||||
if: :password_digest_changed?
|
||||
validates :password,
|
||||
length: { minimum: 8 },
|
||||
presence: true,
|
||||
on: :create
|
||||
|
||||
validates :password_confirmation,
|
||||
presence: true,
|
||||
on: :create
|
||||
validates :password,
|
||||
length: { minimum: 8 },
|
||||
on: :update,
|
||||
if: :password_digest_changed?
|
||||
|
||||
validates :password_confirmation,
|
||||
presence: true,
|
||||
on: :update,
|
||||
if: :password_digest_changed?
|
||||
validates :password_confirmation,
|
||||
presence: true,
|
||||
on: :create
|
||||
|
||||
##### ActiveModel Security
|
||||
has_secure_password
|
||||
validates :password_confirmation,
|
||||
presence: true,
|
||||
on: :update,
|
||||
if: :password_digest_changed?
|
||||
|
||||
def favorite_parties
|
||||
self.favorites.map { |favorite| favorite.party }
|
||||
end
|
||||
##### ActiveModel Security
|
||||
has_secure_password
|
||||
|
||||
def favorite_parties
|
||||
favorites.map(&:party)
|
||||
end
|
||||
|
||||
def blueprint
|
||||
UserBlueprint
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,24 +1,30 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Weapon < ApplicationRecord
|
||||
include PgSearch::Model
|
||||
include PgSearch::Model
|
||||
|
||||
pg_search_scope :en_search,
|
||||
against: :name_en,
|
||||
using: {
|
||||
trigram: {
|
||||
threshold: 0.18
|
||||
}
|
||||
}
|
||||
pg_search_scope :en_search,
|
||||
against: :name_en,
|
||||
using: {
|
||||
trigram: {
|
||||
threshold: 0.18
|
||||
}
|
||||
}
|
||||
|
||||
pg_search_scope :jp_search,
|
||||
against: :name_jp,
|
||||
using: {
|
||||
tsearch: {
|
||||
prefix: true,
|
||||
dictionary: "simple"
|
||||
}
|
||||
}
|
||||
pg_search_scope :jp_search,
|
||||
against: :name_jp,
|
||||
using: {
|
||||
tsearch: {
|
||||
prefix: true,
|
||||
dictionary: 'simple'
|
||||
}
|
||||
}
|
||||
|
||||
def display_resource(weapon)
|
||||
weapon.name_en
|
||||
end
|
||||
def blueprint
|
||||
WeaponBlueprint
|
||||
end
|
||||
|
||||
def display_resource(weapon)
|
||||
weapon.name_en
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,2 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class WeaponKey < ApplicationRecord
|
||||
def blueprint
|
||||
WeaponKeyBlueprint
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
object false
|
||||
|
||||
node :errors do
|
||||
if @exception.respond_to?(:record)
|
||||
errors = ValidationErrorsSerializer.new(@exception.record).serialize
|
||||
end
|
||||
|
||||
if @exception.respond_to?(:message) && @exception.respond_to?(:code)
|
||||
errors = [
|
||||
{
|
||||
message: @exception.message,
|
||||
code: @exception.code
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
errors
|
||||
end
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
object false
|
||||
|
||||
node(:errors) do
|
||||
{
|
||||
'message': "Record could not be found.",
|
||||
'code': 'not_found'
|
||||
}
|
||||
end
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
object :character
|
||||
|
||||
attributes :id,
|
||||
:granblue_id,
|
||||
:character_id,
|
||||
:rarity,
|
||||
:element,
|
||||
:gender,
|
||||
:max_level,
|
||||
:special
|
||||
|
||||
node :name do |w|
|
||||
{
|
||||
:en => w.name_en,
|
||||
:ja => w.name_jp
|
||||
}
|
||||
end
|
||||
|
||||
node :uncap do |w|
|
||||
{
|
||||
:flb => w.flb,
|
||||
:ulb => w.ulb
|
||||
}
|
||||
end
|
||||
|
||||
node :hp do |w|
|
||||
{
|
||||
:min_hp => w.min_hp,
|
||||
:max_hp => w.max_hp,
|
||||
:max_hp_flb => w.max_hp_flb
|
||||
}
|
||||
end
|
||||
|
||||
node :atk do |w|
|
||||
{
|
||||
:min_atk => w.min_atk,
|
||||
:max_atk => w.max_atk,
|
||||
:max_atk_flb => w.max_atk_flb
|
||||
}
|
||||
end
|
||||
|
||||
node :race do |w|
|
||||
[
|
||||
w.race1,
|
||||
w.race2
|
||||
]
|
||||
end
|
||||
|
||||
node :proficiency do |w|
|
||||
[
|
||||
w.proficiency1,
|
||||
w.proficiency2
|
||||
]
|
||||
end
|
||||
|
||||
node :data do |w|
|
||||
{
|
||||
:base_da => w.base_da,
|
||||
:base_ta => w.base_ta,
|
||||
}
|
||||
end
|
||||
|
||||
node :ougi_ratio do |w|
|
||||
{
|
||||
:ougi_ratio => w.ougi_ratio,
|
||||
:ougi_ratio_flb => w.ougi_ratio_flb
|
||||
}
|
||||
end
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
object :favorite
|
||||
|
||||
attributes :id, :user_id, :party_id, :created_at, :updated_at
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
object false
|
||||
|
||||
node :destroyed do
|
||||
true
|
||||
end
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
object @favorite
|
||||
|
||||
extends 'api/v1/favorites/base'
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
attributes :id,
|
||||
:party_id,
|
||||
:position,
|
||||
:uncap_level,
|
||||
:perpetuity,
|
||||
|
||||
node :object do |c|
|
||||
partial("characters/base", :object => c.character)
|
||||
end
|
||||
|
||||
node :awakening do |c|
|
||||
{
|
||||
:type => c.awakening_type,
|
||||
:level => c.awakening_level
|
||||
}
|
||||
end
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
object false
|
||||
|
||||
node :conflicts do
|
||||
partial('grid_characters/base', :object => @conflict_characters)
|
||||
end
|
||||
|
||||
node :incoming do
|
||||
partial('characters/base', :object => @incoming_character)
|
||||
end
|
||||
|
||||
node :position do
|
||||
@incoming_position
|
||||
end
|
||||
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
object @character
|
||||
|
||||
extends 'api/v1/grid_characters/base'
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
attributes :id,
|
||||
:party_id,
|
||||
:main,
|
||||
:friend,
|
||||
:position,
|
||||
:uncap_level
|
||||
|
||||
node :object do |s|
|
||||
partial('summons/base', :object => s.summon)
|
||||
end
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
object @summon
|
||||
|
||||
extends 'api/v1/grid_summons/base'
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
attributes :id,
|
||||
:party_id,
|
||||
:mainhand,
|
||||
:position,
|
||||
:uncap_level,
|
||||
:element
|
||||
|
||||
node :object do |w|
|
||||
partial("weapons/base", :object => w.weapon)
|
||||
end
|
||||
|
||||
node :weapon_keys, :if => lambda { |w| [2, 3, 17, 22].include?(w.weapon.series) } do |w|
|
||||
partial("weapon_keys/base", :object => w.weapon_keys)
|
||||
end
|
||||
|
||||
node :ax, :if => lambda { |w| w.weapon.ax > 0 } do |w|
|
||||
[
|
||||
{
|
||||
:modifier => w.ax_modifier1,
|
||||
:strength => w.ax_strength1
|
||||
},
|
||||
{
|
||||
:modifier => w.ax_modifier2,
|
||||
:strength => w.ax_strength2
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
node :awakening, :if => lambda { |w| w.weapon.awakening } do |w|
|
||||
{
|
||||
:type => w.awakening_type,
|
||||
:level => w.awakening_level
|
||||
}
|
||||
end
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
object @weapon
|
||||
|
||||
extends 'api/v1/grid_weapons/base'
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
object @weapon
|
||||
|
||||
extends 'api/v1/grid_weapons/base'
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
collection @skills, object_root: false
|
||||
|
||||
extends 'job_skills/base'
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
object :job_skill
|
||||
|
||||
attributes :id, :job, :slug, :color, :main, :base, :sub, :emp, :order
|
||||
|
||||
node :name do |w|
|
||||
{
|
||||
:en => w.name_en,
|
||||
:ja => w.name_jp
|
||||
}
|
||||
end
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
collection @jobs, object_root: false
|
||||
|
||||
extends 'jobs/base'
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
object :job
|
||||
|
||||
attributes :id, :row, :ml, :order
|
||||
|
||||
node :name do |j|
|
||||
{
|
||||
:en => j.name_en,
|
||||
:ja => j.name_jp
|
||||
}
|
||||
end
|
||||
|
||||
node :proficiency do |j|
|
||||
[
|
||||
j.proficiency1,
|
||||
j.proficiency2
|
||||
]
|
||||
end
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
object @party
|
||||
|
||||
attributes :id, :user_id, :shortcode
|
||||
|
||||
node :is_extra do |p|
|
||||
p.extra
|
||||
end
|
||||
|
||||
node :job do |p|
|
||||
partial("jobs/base", object: p.job)
|
||||
end
|
||||
|
||||
node :job_skills do |p|
|
||||
{
|
||||
"0" => partial("job_skills/base", object: p.skill0),
|
||||
"1" => partial("job_skills/base", object: p.skill1),
|
||||
"2" => partial("job_skills/base", object: p.skill2),
|
||||
"3" => partial("job_skills/base", object: p.skill3),
|
||||
}
|
||||
end
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
node :count do
|
||||
@count
|
||||
end
|
||||
|
||||
node :total_pages do
|
||||
(@count.to_f / @per_page > 1) ? (@count.to_f / @per_page).ceil() : 1
|
||||
end
|
||||
|
||||
node(:results) {
|
||||
partial('parties/base', object: @parties)
|
||||
} unless @parties.empty?
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
object :party
|
||||
|
||||
attributes :id,
|
||||
:name,
|
||||
:description,
|
||||
:element,
|
||||
:favorited,
|
||||
:shortcode,
|
||||
:created_at,
|
||||
:updated_at
|
||||
|
||||
node :extra do |p|
|
||||
p.extra
|
||||
end
|
||||
|
||||
node :user do |p|
|
||||
partial("users/base", object: p.user)
|
||||
end
|
||||
|
||||
node :raid do |p|
|
||||
partial("raids/base", object: p.raid)
|
||||
end
|
||||
|
||||
node :job do |p|
|
||||
partial("jobs/base", object: p.job)
|
||||
end
|
||||
|
||||
node :job_skills do |p|
|
||||
{
|
||||
"0" => partial("job_skills/base", object: p.skill0),
|
||||
"1" => partial("job_skills/base", object: p.skill1),
|
||||
"2" => partial("job_skills/base", object: p.skill2),
|
||||
"3" => partial("job_skills/base", object: p.skill3),
|
||||
}
|
||||
end
|
||||
|
||||
node :characters do |p|
|
||||
partial("grid_characters/base", object: p.characters)
|
||||
end
|
||||
|
||||
node :weapons do |p|
|
||||
partial("grid_weapons/base", object: p.weapons)
|
||||
end
|
||||
|
||||
node :summons do |p|
|
||||
partial("grid_summons/base", object: p.summons)
|
||||
end
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
object @party
|
||||
|
||||
attributes :id, :name, :description, :shortcode, :favorited, :created_at, :updated_at
|
||||
|
||||
node :user do |p|
|
||||
partial('users/base', :object => p.user)
|
||||
end
|
||||
|
||||
node :raid do |p|
|
||||
partial('raids/base', :object => p.raid)
|
||||
end
|
||||
|
||||
node :characters do |p|
|
||||
partial('grid_characters/base', :object => p.characters)
|
||||
end
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
object false
|
||||
|
||||
node :destroyed do
|
||||
true
|
||||
end
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
object @party
|
||||
|
||||
extends 'api/v1/parties/base'
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
object @party
|
||||
|
||||
attributes :id, :name, :description, :shortcode, :favorited, :created_at, :updated_at
|
||||
|
||||
node :user do |p|
|
||||
partial('users/base', :object => p.user)
|
||||
end
|
||||
|
||||
node :raid do |p|
|
||||
partial('raids/base', :object => p.raid)
|
||||
end
|
||||
|
||||
node :summons do |p|
|
||||
partial('grid_summons/base', :object => p.summons)
|
||||
end
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
object @party
|
||||
|
||||
attributes :id, :user_id, :shortcode
|
||||
|
||||
node :is_extra do |p|
|
||||
p.extra
|
||||
end
|
||||
|
||||
node :job do |p|
|
||||
partial("jobs/base", object: p.job)
|
||||
end
|
||||
|
||||
node :job_skills do |p|
|
||||
{
|
||||
"0" => partial("job_skills/base", object: p.skill0),
|
||||
"1" => partial("job_skills/base", object: p.skill1),
|
||||
"2" => partial("job_skills/base", object: p.skill2),
|
||||
"3" => partial("job_skills/base", object: p.skill3),
|
||||
}
|
||||
end
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
object @party
|
||||
|
||||
attributes :id, :name, :description, :shortcode, :favorited, :created_at, :updated_at
|
||||
|
||||
node :user do |p|
|
||||
partial('users/base', :object => p.user)
|
||||
end
|
||||
|
||||
node :raid do |p|
|
||||
partial('raids/base', :object => p.raid)
|
||||
end
|
||||
|
||||
node :extra do |p|
|
||||
p.extra
|
||||
end
|
||||
|
||||
node :weapons do |p|
|
||||
partial('grid_weapons/base', :object => p.weapons)
|
||||
end
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
collection @raids
|
||||
|
||||
extends 'raids/base'
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
object :raid
|
||||
|
||||
attributes :id, :slug, :level, :group, :element
|
||||
|
||||
node :name do |r|
|
||||
{
|
||||
:en => r.name_en,
|
||||
:ja => r.name_jp
|
||||
}
|
||||
end
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
node :count do
|
||||
@count
|
||||
end
|
||||
|
||||
node :total_pages do
|
||||
(@count.to_f / 10 > 1) ? (@count.to_f / 10).ceil() : 1
|
||||
end
|
||||
|
||||
node(:results) {
|
||||
partial('characters/base', object: @characters)
|
||||
} unless @characters.empty?
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
node :count do
|
||||
@count
|
||||
end
|
||||
|
||||
node :total_pages do
|
||||
(@count.to_f / 10 > 1) ? (@count.to_f / 10).ceil() : 1
|
||||
end
|
||||
|
||||
node(:results) {
|
||||
partial('job_skills/base', object: @skills)
|
||||
} unless @skills.empty?
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
node :count do
|
||||
@count
|
||||
end
|
||||
|
||||
node :total_pages do
|
||||
(@count.to_f / 10 > 1) ? (@count.to_f / 10).ceil() : 1
|
||||
end
|
||||
|
||||
node(:results) {
|
||||
partial('summons/base', object: @summons)
|
||||
} unless @summons.empty?
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
node :count do
|
||||
@count
|
||||
end
|
||||
|
||||
node :total_pages do
|
||||
(@count.to_f / 10 > 1) ? (@count.to_f / 10).ceil() : 1
|
||||
end
|
||||
|
||||
node(:results) {
|
||||
partial('weapons/base', object: @weapons)
|
||||
} unless @weapons.empty?
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
object :summon
|
||||
|
||||
attributes :id,
|
||||
:granblue_id,
|
||||
:element,
|
||||
:rarity,
|
||||
:max_level
|
||||
|
||||
node :name do |w|
|
||||
{
|
||||
:en => w.name_en,
|
||||
:ja => w.name_jp
|
||||
}
|
||||
end
|
||||
|
||||
node :uncap do |w|
|
||||
{
|
||||
:flb => w.flb,
|
||||
:ulb => w.ulb
|
||||
}
|
||||
end
|
||||
|
||||
node :hp do |w|
|
||||
{
|
||||
:min_hp => w.min_hp,
|
||||
:max_hp => w.max_hp,
|
||||
:max_hp_flb => w.max_hp_flb,
|
||||
:max_hp_ulb => w.max_hp_ulb
|
||||
}
|
||||
end
|
||||
|
||||
node :atk do |w|
|
||||
{
|
||||
:min_atk => w.min_atk,
|
||||
:max_atk => w.max_atk,
|
||||
:max_atk_flb => w.max_atk_flb,
|
||||
:max_atk_ulb => w.max_atk_ulb
|
||||
}
|
||||
end
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
object false
|
||||
|
||||
node(:available) {
|
||||
@available
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
object :user
|
||||
|
||||
attributes :id,
|
||||
:username,
|
||||
:granblue_id,
|
||||
:language,
|
||||
:private,
|
||||
:gender
|
||||
|
||||
node :picture do |u|
|
||||
{
|
||||
:picture => u.picture,
|
||||
:element => u.element
|
||||
}
|
||||
end
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
object false
|
||||
|
||||
node(:user) {
|
||||
@presenter
|
||||
} unless @user.blank?
|
||||
|
||||
node(:error) {
|
||||
@error
|
||||
} unless @error.blank?
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
object @user
|
||||
|
||||
extends 'api/v1/users/base'
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue