From c1716c1e4f265ecf9510c827448c5b3a4133970e Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 00:22:47 -0800 Subject: [PATCH 01/42] Run RuboCop on everything yolo --- app/controllers/api/v1/api_controller.rb | 140 ++++---- .../api/v1/favorites_controller.rb | 53 +-- .../api/v1/grid_characters_controller.rb | 124 +++---- .../api/v1/grid_summons_controller.rb | 53 ++- .../api/v1/grid_weapons_controller.rb | 76 ++--- .../api/v1/job_skills_controller.rb | 18 +- app/controllers/api/v1/jobs_controller.rb | 287 ++++++++-------- app/controllers/api/v1/parties_controller.rb | 321 +++++++++--------- app/controllers/api/v1/raids_controller.rb | 14 +- app/controllers/api/v1/search_controller.rb | 271 ++++++++------- app/controllers/api/v1/users_controller.rb | 144 ++++---- .../api/v1/weapon_keys_controller.rb | 12 +- app/controllers/application_controller.rb | 10 +- app/controllers/tokens_controller.rb | 62 ++-- .../api/v1/FavoriteAlreadyExistsError.rb | 22 -- app/errors/api/v1/IncompatibleSkillError.rb | 29 -- app/errors/api/v1/NoJobProvidedError.rb | 22 -- app/errors/api/v1/NoJobSkillProvidedError.rb | 22 -- app/errors/api/v1/UnauthorizedError.rb | 22 -- .../api/v1/favorite_already_exists_error.rb | 26 ++ .../{GranblueError.rb => granblue_error.rb} | 0 app/errors/api/v1/incompatible_skill_error.rb | 33 ++ app/errors/api/v1/no_job_provided_error.rb | 26 ++ .../api/v1/no_job_skill_provided_error.rb | 26 ++ ...erError.rb => same_favorite_user_error.rb} | 2 + ...or.rb => too_many_skills_of_type_error.rb} | 0 app/errors/api/v1/unauthorized_error.rb | 26 ++ app/helpers/validation_error_serializer.rb | 54 +-- app/helpers/validation_errors_serializer.rb | 25 +- app/models/application_record.rb | 2 + app/models/character.rb | 165 ++++----- app/models/favorite.rb | 14 +- app/models/grid_character.rb | 12 +- app/models/grid_summon.rb | 12 +- app/models/grid_weapon.rb | 32 +- app/models/job.rb | 2 + app/models/job_skill.rb | 14 +- app/models/party.rb | 46 ++- app/models/raid.rb | 2 + app/models/summon.rb | 40 +-- app/models/user.rb | 68 ++-- app/models/weapon.rb | 40 +-- app/models/weapon_key.rb | 2 + config/environments/development.rb | 5 + spec/requests/job_skills_spec.rb | 7 + 45 files changed, 1251 insertions(+), 1132 deletions(-) delete mode 100644 app/errors/api/v1/FavoriteAlreadyExistsError.rb delete mode 100644 app/errors/api/v1/IncompatibleSkillError.rb delete mode 100644 app/errors/api/v1/NoJobProvidedError.rb delete mode 100644 app/errors/api/v1/NoJobSkillProvidedError.rb delete mode 100644 app/errors/api/v1/UnauthorizedError.rb create mode 100644 app/errors/api/v1/favorite_already_exists_error.rb rename app/errors/api/v1/{GranblueError.rb => granblue_error.rb} (100%) create mode 100644 app/errors/api/v1/incompatible_skill_error.rb create mode 100644 app/errors/api/v1/no_job_provided_error.rb create mode 100644 app/errors/api/v1/no_job_skill_provided_error.rb rename app/errors/api/v1/{SameFavoriteUserError.rb => same_favorite_user_error.rb} (91%) rename app/errors/api/v1/{TooManySkillsOfTypeError.rb => too_many_skills_of_type_error.rb} (100%) create mode 100644 app/errors/api/v1/unauthorized_error.rb create mode 100644 spec/requests/job_skills_spec.rb diff --git a/app/controllers/api/v1/api_controller.rb b/app/controllers/api/v1/api_controller.rb index 79e13a9..e7a7c37 100644 --- a/app/controllers/api/v1/api_controller.rb +++ b/app/controllers/api/v1/api_controller.rb @@ -1,80 +1,84 @@ -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 + 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 :set_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 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' + end + end + + def render_unprocessable_entity_response(exception) + @exception = exception + render action: 'errors', status: :unprocessable_entity + end + + def render_not_found_response + response = { errors: [{ message: 'Record could not be found.', code: 'not_found' }] } + render 'not_found', status: :not_found + end + + def render_unauthorized_response + render action: 'errors', status: :unauthorized + end + + private + + def restrict_access + raise UnauthorizedError unless current_user + end end end end diff --git a/app/controllers/api/v1/favorites_controller.rb b/app/controllers/api/v1/favorites_controller.rb index 26da814..177f2f2 100644 --- a/app/controllers/api/v1/favorites_controller.rb +++ b/app/controllers/api/v1/favorites_controller.rb @@ -1,41 +1,42 @@ -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! - end - end + @favorite = Favorite.new({ + user_id: current_user.id, + party_id: party_id + }) + render :show, status: :created if @favorite.save! + end - def destroy + 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 + end - private + private - def set_party - @party = Party.where("id = ?", params[:party_id]).first - end + def set_party + @party = Party.where('id = ?', params[:party_id]).first + end - def favorite_params + def favorite_params params.require(:favorite).permit(:party_id) + end end -end \ No newline at end of file + end +end diff --git a/app/controllers/api/v1/grid_characters_controller.rb b/app/controllers/api/v1/grid_characters_controller.rb index 9d6ece3..4848d8b 100644 --- a/app/controllers/api/v1/grid_characters_controller.rb +++ b/app/controllers/api/v1/grid_characters_controller.rb @@ -1,53 +1,54 @@ -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 + @conflict_characters = conflict_characters + @incoming_character = incoming_character + @incoming_position = character_params[:position] + + render :conflict, status: :ok 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 :show, 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 +58,45 @@ 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 + 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.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 - end + render_unauthorized_response if current_user && (@character.party.user != current_user) @character.uncap_level = character_params[:uncap_level] render :show, status: :ok if @character.save! - end + end - def destroy - end + def destroy; end - private + 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 + # 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 => []) + def resolve_params + params.require(:resolve).permit(:position, :incoming, conflicting: []) + end end + end end diff --git a/app/controllers/api/v1/grid_summons_controller.rb b/app/controllers/api/v1/grid_summons_controller.rb index 4198e46..3db26e7 100644 --- a/app/controllers/api/v1/grid_summons_controller.rb +++ b/app/controllers/api/v1/grid_summons_controller.rb @@ -1,45 +1,42 @@ -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 - end - if grid_summon = GridSummon.where( - party_id: party.id, - position: summon_params[:position] - ).first - GridSummon.destroy(grid_summon.id) + 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 @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 + end + + 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 + end - def destroy - end + def destroy; end - private + private - # Specify whitelisted properties that can be modified. - def summon_params + # 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 \ No newline at end of file + end +end diff --git a/app/controllers/api/v1/grid_weapons_controller.rb b/app/controllers/api/v1/grid_weapons_controller.rb index a2dfa7a..07cefdb 100644 --- a/app/controllers/api/v1/grid_weapons_controller.rb +++ b/app/controllers/api/v1/grid_weapons_controller.rb @@ -1,39 +1,37 @@ -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 - end + render_unauthorized_response if current_user && (party.user != current_user) if grid_weapon = GridWeapon.where( - party_id: party.id, - position: weapon_params[:position] + party_id: party.id, + position: weapon_params[:position] ).first - GridWeapon.destroy(grid_weapon.id) + GridWeapon.destroy(grid_weapon.id) end @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! + if @weapon.position == -1 + party.element = @weapon.weapon.element + party.save! end render :show, status: :created if @weapon.save! - end + 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) + + ap weapon_params # TODO: Server-side validation of weapon mods # We don't want someone modifying the JSON and adding @@ -42,34 +40,32 @@ 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 + end - def update_uncap_level + def update_uncap_level @weapon = GridWeapon.find(weapon_params[:id]) - if current_user - if party.user != current_user - render_unauthorized_response - end - end + render_unauthorized_response if current_user && (party.user != current_user) @weapon.uncap_level = weapon_params[:uncap_level] render :show, status: :ok if @weapon.save! - end + end - private + private - def set - @weapon = GridWeapon.where("id = ?", params[:id]).first - end + def set + @weapon = GridWeapon.where('id = ?', params[:id]).first + end - # Specify whitelisted properties that can be modified. - def weapon_params + # 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 \ No newline at end of file + end +end diff --git a/app/controllers/api/v1/job_skills_controller.rb b/app/controllers/api/v1/job_skills_controller.rb index 24d519f..d5a5864 100644 --- a/app/controllers/api/v1/job_skills_controller.rb +++ b/app/controllers/api/v1/job_skills_controller.rb @@ -1,13 +1,19 @@ -class Api::V1::JobSkillsController < Api::V1::ApiController - def all - @skills = JobSkill.all() - render :all, status: :ok - end +# frozen_string_literal: true - def job +module Api + module V1 + class JobSkillsController < Api::V1::ApiController + def all + @skills = JobSkill.all + render :all, status: :ok + end + + def job job = Job.find(params[:id]) @skills = JobSkill.where(job: job).or(JobSkill.where(sub: true)) render :all, status: :ok + end end + end end diff --git a/app/controllers/api/v1/jobs_controller.rb b/app/controllers/api/v1/jobs_controller.rb index 74d5a9a..7fbe75b 100644 --- a/app/controllers/api/v1/jobs_controller.rb +++ b/app/controllers/api/v1/jobs_controller.rb @@ -1,160 +1,167 @@ -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 + @jobs = Job.all + render :all, status: :ok 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 + raise NoJobProvidedError unless job_params[:job_id].present? - new_skill_ids = new_skills.each_with_object({}) do |(index, skill), memo| - memo["skill#{index}_id"] = skill.id if skill + # 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 - @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 :update, status: :ok 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 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 - - 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 diff --git a/app/controllers/api/v1/parties_controller.rb b/app/controllers/api/v1/parties_controller.rb index 9ed82f9..5a7d88a 100644 --- a/app/controllers/api/v1/parties_controller.rb +++ b/app/controllers/api/v1/parties_controller.rb @@ -1,162 +1,171 @@ -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 + class PartiesController < Api::V1::ApiController + before_action :set_from_slug, + except: %w[create destroy update index favorites] + before_action :set, only: %w[update destroy] - 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 + def create + @party = Party.new(shortcode: random_string) + @party.extra = party_params['extra'] + + 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 + + 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 + unless request.params['recency'].blank? + start_time = + ( + now - request.params['recency'].to_i.seconds + ).to_datetime.beginning_of_day + end + + 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 + unless request.params['recency'].blank? + start_time = + ( + now - params['recency'].to_i.seconds + ).to_datetime.beginning_of_day + end + + 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 + 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 diff --git a/app/controllers/api/v1/raids_controller.rb b/app/controllers/api/v1/raids_controller.rb index cac3b93..6e9e51c 100644 --- a/app/controllers/api/v1/raids_controller.rb +++ b/app/controllers/api/v1/raids_controller.rb @@ -1,6 +1,12 @@ -class Api::V1::RaidsController < Api::V1::ApiController - def all - @raids = Raid.all() +# frozen_string_literal: true + +module Api + module V1 + class RaidsController < Api::V1::ApiController + def all + @raids = Raid.all render :all, status: :ok + end end -end \ No newline at end of file + end +end diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb index 9f42fc6..e40f394 100644 --- a/app/controllers/api/v1/search_controller.rb +++ b/app/controllers/api/v1/search_controller.rb @@ -1,139 +1,154 @@ -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 + class SearchController < Api::V1::ApiController + def characters + filters = search_params[:filters] + locale = search_params[:locale] || 'en' + conditions = {} - @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 + 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 + @characters = @characters.paginate(page: search_params[:page], per_page: 10) + 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' + Weapon.jp_search(search_params[:query]).where(conditions) + else + Weapon.en_search(search_params[:query]).where(conditions) + end + else + Weapon.where(conditions) + end + + @count = @weapons.length + @weapons = @weapons.paginate(page: search_params[:page], per_page: 10) + end + + def summons + 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? + 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 + @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 + 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 - Character.where(conditions) + 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 = @characters.length - @characters = @characters.paginate(page: search_params[:page], per_page: 10) - end + @count = @skills.length + @skills = @skills.paginate(page: search_params[:page], per_page: 10) + end - def weapons - filters = search_params[:filters] - locale = search_params[:locale] || 'en' - conditions = {} + private - 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 - - @weapons = if search_params[:query].present? && search_params[:query].length >= 2 - if locale == 'ja' - Weapon.jp_search(search_params[:query]).where(conditions) - else - Weapon.en_search(search_params[:query]).where(conditions) - end - else - Weapon.where(conditions) - end - - @count = @weapons.length - @weapons = @weapons.paginate(page: search_params[:page], per_page: 10) - end - - def summons - 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? - 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 - @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 diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb index a7340e5..98a4ebc 100644 --- a/app/controllers/api/v1/users_controller.rb +++ b/app/controllers/api/v1/users_controller.rb @@ -1,103 +1,109 @@ -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 + class UsersController < Api::V1::ApiController + class ForbiddenError < StandardError; end - def 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) token = Doorkeeper::AccessToken.create!( - application_id: nil, - resource_owner_id: @user.id, - expires_in: 30.days, - scopes: 'public' + application_id: nil, + resource_owner_id: @user.id, + expires_in: 30.days, + scopes: 'public' ).token - if @user.save! - @presenter = { - user_id: @user.id, - username: @user.username, - token: token - } + return unless @user.save! - render :create, status: :created - end - end + @presenter = { + user_id: @user.id, + username: @user.username, + token: token + } + render :create, status: :created + end - def update + def update render :info, status: :ok if @user.update(user_params) - end + end - def info + def info render :info, status: :ok - end + end - def show + def show if @user - @per_page = 15 + @per_page = 15 - now = DateTime.current - start_time = (now - params['recency'].to_i.seconds).to_datetime.beginning_of_day unless request.params['recency'].blank? + now = DateTime.current + unless request.params['recency'].blank? + start_time = (now - params['recency'].to_i.seconds).to_datetime.beginning_of_day + end - 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 + 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 + @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 else - render_not_found_response + render_not_found_response end - end + end - def check_email - if params[:email].present? - @available = User.where("email = ?", params[:email]).count == 0 - else - @available = false - end + def check_email + @available = if params[:email].present? + User.where('email = ?', params[:email]).count.zero? + else + false + end render :available - end + end - def check_username - if params[:username].present? - @available = User.where("username = ?", params[:username]).count == 0 - else - @available = false - end + def check_username + @available = if params[:username].present? + User.where('username = ?', params[:username]).count.zero? + else + false + end render :available - end + end - def destroy - end + def destroy; end - private + private - # Specify whitelisted properties that can be modified. - def set - @user = User.where("username = ?", params[:id]).first - 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 set_by_id + @user = User.where('id = ?', params[:id]).first + end - def user_params + 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 \ No newline at end of file + end +end diff --git a/app/controllers/api/v1/weapon_keys_controller.rb b/app/controllers/api/v1/weapon_keys_controller.rb index b51ae6d..8bdcaaa 100644 --- a/app/controllers/api/v1/weapon_keys_controller.rb +++ b/app/controllers/api/v1/weapon_keys_controller.rb @@ -1,5 +1,9 @@ -class Api::V1::WeaponKeysController < Api::V1::ApiController - def all +# frozen_string_literal: true + +module Api + module V1 + class WeaponKeysController < Api::V1::ApiController + def all conditions = {} conditions[:series] = request.params['series'] conditions[:slot] = request.params['slot'] @@ -7,5 +11,7 @@ class Api::V1::WeaponKeysController < Api::V1::ApiController @keys = WeaponKey.where(conditions) render :all, status: :ok + end end -end \ No newline at end of file + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ed40efb..8f3f575 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,6 +1,8 @@ +# 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" + # 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 diff --git a/app/controllers/tokens_controller.rb b/app/controllers/tokens_controller.rb index b61b6ca..b78ba70 100644 --- a/app/controllers/tokens_controller.rb +++ b/app/controllers/tokens_controller.rb @@ -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 - \ No newline at end of file diff --git a/app/errors/api/v1/FavoriteAlreadyExistsError.rb b/app/errors/api/v1/FavoriteAlreadyExistsError.rb deleted file mode 100644 index e0ac7b7..0000000 --- a/app/errors/api/v1/FavoriteAlreadyExistsError.rb +++ /dev/null @@ -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 diff --git a/app/errors/api/v1/IncompatibleSkillError.rb b/app/errors/api/v1/IncompatibleSkillError.rb deleted file mode 100644 index bd8c808..0000000 --- a/app/errors/api/v1/IncompatibleSkillError.rb +++ /dev/null @@ -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 diff --git a/app/errors/api/v1/NoJobProvidedError.rb b/app/errors/api/v1/NoJobProvidedError.rb deleted file mode 100644 index c27f48a..0000000 --- a/app/errors/api/v1/NoJobProvidedError.rb +++ /dev/null @@ -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 diff --git a/app/errors/api/v1/NoJobSkillProvidedError.rb b/app/errors/api/v1/NoJobSkillProvidedError.rb deleted file mode 100644 index 60ad888..0000000 --- a/app/errors/api/v1/NoJobSkillProvidedError.rb +++ /dev/null @@ -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 diff --git a/app/errors/api/v1/UnauthorizedError.rb b/app/errors/api/v1/UnauthorizedError.rb deleted file mode 100644 index 842c178..0000000 --- a/app/errors/api/v1/UnauthorizedError.rb +++ /dev/null @@ -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 diff --git a/app/errors/api/v1/favorite_already_exists_error.rb b/app/errors/api/v1/favorite_already_exists_error.rb new file mode 100644 index 0000000..cd49d95 --- /dev/null +++ b/app/errors/api/v1/favorite_already_exists_error.rb @@ -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 diff --git a/app/errors/api/v1/GranblueError.rb b/app/errors/api/v1/granblue_error.rb similarity index 100% rename from app/errors/api/v1/GranblueError.rb rename to app/errors/api/v1/granblue_error.rb diff --git a/app/errors/api/v1/incompatible_skill_error.rb b/app/errors/api/v1/incompatible_skill_error.rb new file mode 100644 index 0000000..6168feb --- /dev/null +++ b/app/errors/api/v1/incompatible_skill_error.rb @@ -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 diff --git a/app/errors/api/v1/no_job_provided_error.rb b/app/errors/api/v1/no_job_provided_error.rb new file mode 100644 index 0000000..70579a2 --- /dev/null +++ b/app/errors/api/v1/no_job_provided_error.rb @@ -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 diff --git a/app/errors/api/v1/no_job_skill_provided_error.rb b/app/errors/api/v1/no_job_skill_provided_error.rb new file mode 100644 index 0000000..38b89b8 --- /dev/null +++ b/app/errors/api/v1/no_job_skill_provided_error.rb @@ -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 diff --git a/app/errors/api/v1/SameFavoriteUserError.rb b/app/errors/api/v1/same_favorite_user_error.rb similarity index 91% rename from app/errors/api/v1/SameFavoriteUserError.rb rename to app/errors/api/v1/same_favorite_user_error.rb index 6fbcc79..73f95df 100644 --- a/app/errors/api/v1/SameFavoriteUserError.rb +++ b/app/errors/api/v1/same_favorite_user_error.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Api module V1 class SameFavoriteUserError < GranblueError diff --git a/app/errors/api/v1/TooManySkillsOfTypeError.rb b/app/errors/api/v1/too_many_skills_of_type_error.rb similarity index 100% rename from app/errors/api/v1/TooManySkillsOfTypeError.rb rename to app/errors/api/v1/too_many_skills_of_type_error.rb diff --git a/app/errors/api/v1/unauthorized_error.rb b/app/errors/api/v1/unauthorized_error.rb new file mode 100644 index 0000000..70aea6d --- /dev/null +++ b/app/errors/api/v1/unauthorized_error.rb @@ -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 diff --git a/app/helpers/validation_error_serializer.rb b/app/helpers/validation_error_serializer.rb index 730f0b6..ad22738 100644 --- a/app/helpers/validation_error_serializer.rb +++ b/app/helpers/validation_error_serializer.rb @@ -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 \ No newline at end of file + def underscored_resource_name + @record.class.to_s.gsub('::', '').underscore + end +end diff --git a/app/helpers/validation_errors_serializer.rb b/app/helpers/validation_errors_serializer.rb index af2affa..820ebd2 100644 --- a/app/helpers/validation_errors_serializer.rb +++ b/app/helpers/validation_errors_serializer.rb @@ -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 \ No newline at end of file + 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 diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 10a4cba..71fbba5 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ApplicationRecord < ActiveRecord::Base self.abstract_class = true end diff --git a/app/models/character.rb b/app/models/character.rb index fd3a1b5..631614c 100644 --- a/app/models/character.rb +++ b/app/models/character.rb @@ -1,94 +1,95 @@ +# 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 display_resource(character) + character.name_en + end - # enum rarities: { - # R: 1, - # SR: 2, - # SSR: 3 - # } + # enum rarities: { + # R: 1, + # SR: 2, + # SSR: 3 + # } - # enum elements: { - # Null: 0, - # Wind: 1, - # Fire: 2, - # Water: 3, - # Earth: 4, - # Dark: 5, - # Light: 6 - # } + # enum elements: { + # Null: 0, + # Wind: 1, + # Fire: 2, + # Water: 3, + # Earth: 4, + # Dark: 5, + # Light: 6 + # } - # 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 proficiency1s: { + # Sabre: 1, + # Dagger: 2, + # Axe: 3, + # Spear: 4, + # Bow: 5, + # Staff: 6, + # Melee: 7, + # Harp: 8, + # Gun: 9, + # Katana: 10 + # }, _prefix: "proficiency1" - # 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 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 race1s: { - # Unknown: 0, - # Human: 1, - # Erune: 2, - # Draph: 3, - # Harvin: 4, - # Primal: 5 - # }, _prefix: "race1" + # enum race1s: { + # Unknown: 0, + # Human: 1, + # Erune: 2, + # Draph: 3, + # Harvin: 4, + # Primal: 5 + # }, _prefix: "race1" - # 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 - # } + # 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 diff --git a/app/models/favorite.rb b/app/models/favorite.rb index a074c9a..13c5992 100644 --- a/app/models/favorite.rb +++ b/app/models/favorite.rb @@ -1,8 +1,10 @@ -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 end diff --git a/app/models/grid_character.rb b/app/models/grid_character.rb index 6ac365c..badf5f9 100644 --- a/app/models/grid_character.rb +++ b/app/models/grid_character.rb @@ -1,7 +1,9 @@ -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 end diff --git a/app/models/grid_summon.rb b/app/models/grid_summon.rb index cf6b177..0f95dd8 100644 --- a/app/models/grid_summon.rb +++ b/app/models/grid_summon.rb @@ -1,7 +1,9 @@ -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 end diff --git a/app/models/grid_weapon.rb b/app/models/grid_weapon.rb index aed825e..295b30c 100644 --- a/app/models/grid_weapon.rb +++ b/app/models/grid_weapon.rb @@ -1,21 +1,23 @@ +# 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 end diff --git a/app/models/job.rb b/app/models/job.rb index bded82e..66420a9 100644 --- a/app/models/job.rb +++ b/app/models/job.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Job < ApplicationRecord belongs_to :party diff --git a/app/models/job_skill.rb b/app/models/job_skill.rb index 3ab1d84..b1109ea 100644 --- a/app/models/job_skill.rb +++ b/app/models/job_skill.rb @@ -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,15 @@ class JobSkill < ApplicationRecord using: { tsearch: { prefix: true, - dictionary: "simple", - }, + dictionary: 'simple' + } } 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 diff --git a/app/models/party.rb b/app/models/party.rb index 8c6ef3d..fe2b45e 100644 --- a/app/models/party.rb +++ b/app/models/party.rb @@ -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 @@ -55,18 +57,14 @@ class Party < ApplicationRecord 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 diff --git a/app/models/raid.rb b/app/models/raid.rb index c1065ee..7d4a12b 100644 --- a/app/models/raid.rb +++ b/app/models/raid.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + class Raid < ApplicationRecord end diff --git a/app/models/summon.rb b/app/models/summon.rb index bec63b6..775d61d 100644 --- a/app/models/summon.rb +++ b/app/models/summon.rb @@ -1,24 +1,26 @@ +# 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 display_resource(summon) + summon.name_en + end end diff --git a/app/models/user.rb b/app/models/user.rb index b54636a..44a0e76 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,43 +1,45 @@ +# 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 end diff --git a/app/models/weapon.rb b/app/models/weapon.rb index 6662330..646f82c 100644 --- a/app/models/weapon.rb +++ b/app/models/weapon.rb @@ -1,24 +1,26 @@ +# 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 display_resource(weapon) + weapon.name_en + end end diff --git a/app/models/weapon_key.rb b/app/models/weapon_key.rb index ac981cb..4615b11 100644 --- a/app/models/weapon_key.rb +++ b/app/models/weapon_key.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + class WeaponKey < ApplicationRecord end diff --git a/config/environments/development.rb b/config/environments/development.rb index 143f8d4..6e13811 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,4 +1,9 @@ Rails.application.configure do + config.after_initialize do + ActiveRecord::Base.logger = Rails.logger.clone + ActiveRecord::Base.logger.level = Logger::INFO + end + # Settings specified here will take precedence over those in config/application.rb. config.hosts << "grid-api.ngrok.io" diff --git a/spec/requests/job_skills_spec.rb b/spec/requests/job_skills_spec.rb new file mode 100644 index 0000000..baadd9d --- /dev/null +++ b/spec/requests/job_skills_spec.rb @@ -0,0 +1,7 @@ +require 'rails_helper' + +RSpec.describe "JobSkills", type: :request do + describe "GET /index" do + pending "add some examples (or delete) #{__FILE__}" + end +end From b584a523c650830a11ff2eeec18be5e6b65fbfcf Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 01:13:46 -0800 Subject: [PATCH 02/42] Install blueprinter --- Gemfile | 39 +++++++++++++++++++++------------------ Gemfile.lock | 2 ++ 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/Gemfile b/Gemfile index e247f01..426905a 100644 --- a/Gemfile +++ b/Gemfile @@ -19,6 +19,9 @@ 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' @@ -44,31 +47,31 @@ gem 'pg_search' gem 'will_paginate', '~> 3.3' group :doc do - gem 'sdoc' - gem 'apipie-rails' + gem 'sdoc' + gem 'apipie-rails' 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-rails' + gem 'rspec_junit_formatter' end group :development do - gem 'listen' - gem 'rubocop' - gem 'solargraph' - gem 'spring-commands-rspec' - gem 'spring' + gem 'listen' + gem 'rubocop' + gem 'solargraph' + gem 'spring-commands-rspec' + gem 'spring' 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 diff --git a/Gemfile.lock b/Gemfile.lock index c7f2096..ffabc4b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) @@ -286,6 +287,7 @@ DEPENDENCIES awesome_nested_set awesome_print bcrypt + blueprinter bootsnap byebug database_cleaner From 712c866296f8232cb3bb80fc707fefc8e61c61f0 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 01:16:34 -0800 Subject: [PATCH 03/42] Remove rabl --- Gemfile | 17 +++++++---------- Gemfile.lock | 3 --- app/controllers/application_controller.rb | 4 ---- config/initializers/rabl.rb | 3 --- 4 files changed, 7 insertions(+), 20 deletions(-) delete mode 100644 config/initializers/rabl.rb diff --git a/Gemfile b/Gemfile index 426905a..586f285 100644 --- a/Gemfile +++ b/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,9 +16,6 @@ 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' @@ -38,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' @@ -47,8 +44,8 @@ gem 'pg_search' gem 'will_paginate', '~> 3.3' group :doc do - gem 'sdoc' gem 'apipie-rails' + gem 'sdoc' end group :development, :test do @@ -56,16 +53,16 @@ group :development, :test do gem 'dotenv-rails' gem 'factory_bot_rails' gem 'faker' - gem 'rspec-rails' gem 'rspec_junit_formatter' + gem 'rspec-rails' end group :development do gem 'listen' gem 'rubocop' gem 'solargraph' - gem 'spring-commands-rspec' gem 'spring' + gem 'spring-commands-rspec' end group :test do @@ -73,5 +70,5 @@ group :test do gem 'byebug' gem 'database_cleaner' gem 'shoulda-matchers' - gem 'simplecov', :require => false + gem 'simplecov', require: false end diff --git a/Gemfile.lock b/Gemfile.lock index ffabc4b..eb88c9c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -148,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) @@ -303,7 +301,6 @@ DEPENDENCIES pg pg_search puma - rabl rack-cors rails responders diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 8f3f575..13c271f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,8 +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 diff --git a/config/initializers/rabl.rb b/config/initializers/rabl.rb deleted file mode 100644 index 8bdb4fe..0000000 --- a/config/initializers/rabl.rb +++ /dev/null @@ -1,3 +0,0 @@ -Rabl.configure do |config| - config.view_paths = [Rails.root.join('app', 'views', 'api', 'v1')] -end \ No newline at end of file From 7720d5400f24302014749e5104bab1eaae3df434 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 01:17:04 -0800 Subject: [PATCH 04/42] Configure Blueprinter --- config/initializers/blueprinter.rb | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 config/initializers/blueprinter.rb diff --git a/config/initializers/blueprinter.rb b/config/initializers/blueprinter.rb new file mode 100644 index 0000000..3347aca --- /dev/null +++ b/config/initializers/blueprinter.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +require 'oj' # you can skip this if OJ has already been required. + +Blueprinter.configure do |config| + config.generator = Oj # default is JSON + # config.sort_fields_by = :definition +end From 31e62e073c2bb74bb2cd6a7d893984065798ac30 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 01:20:13 -0800 Subject: [PATCH 05/42] Create api_blueprint.rb --- app/blueprints/api/v1/api_blueprint.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 app/blueprints/api/v1/api_blueprint.rb diff --git a/app/blueprints/api/v1/api_blueprint.rb b/app/blueprints/api/v1/api_blueprint.rb new file mode 100644 index 0000000..edae6bb --- /dev/null +++ b/app/blueprints/api/v1/api_blueprint.rb @@ -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 From a1ff18092d4fe3a6e162e690c5088ee300cf05aa Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 01:20:55 -0800 Subject: [PATCH 06/42] Create error_blueprint.rb --- app/blueprints/api/v1/error_blueprint.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 app/blueprints/api/v1/error_blueprint.rb diff --git a/app/blueprints/api/v1/error_blueprint.rb b/app/blueprints/api/v1/error_blueprint.rb new file mode 100644 index 0000000..92a9580 --- /dev/null +++ b/app/blueprints/api/v1/error_blueprint.rb @@ -0,0 +1,15 @@ +# 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 + end + end +end From c102d68dd7b050d669ffefd8ebc53e53da915090 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 03:31:24 -0800 Subject: [PATCH 07/42] Update blueprinter.rb --- config/initializers/blueprinter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/blueprinter.rb b/config/initializers/blueprinter.rb index 3347aca..2b4eb99 100644 --- a/config/initializers/blueprinter.rb +++ b/config/initializers/blueprinter.rb @@ -4,5 +4,5 @@ require 'oj' # you can skip this if OJ has already been required. Blueprinter.configure do |config| config.generator = Oj # default is JSON - # config.sort_fields_by = :definition + config.sort_fields_by = :definition end From e541182e36b592a3063bcb4a478e49e5664f0e1a Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 03:31:55 -0800 Subject: [PATCH 08/42] Add all blueprints and associate with models --- app/blueprints/api/v1/character_blueprint.rb | 68 +++++++++++++++++++ .../api/v1/grid_character_blueprint.rb | 16 +++++ .../api/v1/grid_summon_blueprint.rb | 16 +++++ .../api/v1/grid_weapon_blueprint.rb | 35 ++++++++++ app/blueprints/api/v1/job_blueprint.rb | 23 +++++++ app/blueprints/api/v1/job_skill_blueprint.rb | 20 ++++++ app/blueprints/api/v1/party_blueprint.rb | 43 ++++++++++++ app/blueprints/api/v1/raid_blueprint.rb | 15 ++++ app/blueprints/api/v1/summon_blueprint.rb | 41 +++++++++++ app/blueprints/api/v1/user_blueprint.rb | 29 ++++++++ app/blueprints/api/v1/weapon_blueprint.rb | 43 ++++++++++++ app/blueprints/api/v1/weapon_key_blueprint.rb | 8 +++ app/models/character.rb | 4 ++ app/models/favorite.rb | 4 ++ app/models/grid_character.rb | 4 ++ app/models/grid_summon.rb | 4 ++ app/models/grid_weapon.rb | 4 ++ app/models/job.rb | 4 ++ app/models/job_skill.rb | 4 ++ app/models/party.rb | 4 ++ app/models/raid.rb | 3 + app/models/summon.rb | 4 ++ app/models/user.rb | 4 ++ app/models/weapon.rb | 4 ++ app/models/weapon_key.rb | 3 + 25 files changed, 407 insertions(+) create mode 100644 app/blueprints/api/v1/character_blueprint.rb create mode 100644 app/blueprints/api/v1/grid_character_blueprint.rb create mode 100644 app/blueprints/api/v1/grid_summon_blueprint.rb create mode 100644 app/blueprints/api/v1/grid_weapon_blueprint.rb create mode 100644 app/blueprints/api/v1/job_blueprint.rb create mode 100644 app/blueprints/api/v1/job_skill_blueprint.rb create mode 100644 app/blueprints/api/v1/party_blueprint.rb create mode 100644 app/blueprints/api/v1/raid_blueprint.rb create mode 100644 app/blueprints/api/v1/summon_blueprint.rb create mode 100644 app/blueprints/api/v1/user_blueprint.rb create mode 100644 app/blueprints/api/v1/weapon_blueprint.rb create mode 100644 app/blueprints/api/v1/weapon_key_blueprint.rb diff --git a/app/blueprints/api/v1/character_blueprint.rb b/app/blueprints/api/v1/character_blueprint.rb new file mode 100644 index 0000000..1fe220e --- /dev/null +++ b/app/blueprints/api/v1/character_blueprint.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +module Api + module V1 + class CharacterBlueprint < ApiBlueprint + fields :id, :granblue_id, :character_id, :rarity, + :element, :gender, :special + + field :name do |w| + { + en: w.name_en, + ja: w.name_jp + } + end + + 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 diff --git a/app/blueprints/api/v1/grid_character_blueprint.rb b/app/blueprints/api/v1/grid_character_blueprint.rb new file mode 100644 index 0000000..5984c71 --- /dev/null +++ b/app/blueprints/api/v1/grid_character_blueprint.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Api + module V1 + class GridCharacterBlueprint < ApiBlueprint + view :nested do + fields :id, :position, :uncap_level, :perpetuity + association :character, name: :object, blueprint: CharacterBlueprint + end + + view :full do + fields :party_id + end + end + end +end diff --git a/app/blueprints/api/v1/grid_summon_blueprint.rb b/app/blueprints/api/v1/grid_summon_blueprint.rb new file mode 100644 index 0000000..ae9c58b --- /dev/null +++ b/app/blueprints/api/v1/grid_summon_blueprint.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Api + module V1 + class GridSummonBlueprint < ApiBlueprint + view :nested do + fields :id, :main, :friend, :position, :uncap_level + association :summon, name: :object, blueprint: SummonBlueprint + end + + view :full do + fields :party_id + end + end + end +end diff --git a/app/blueprints/api/v1/grid_weapon_blueprint.rb b/app/blueprints/api/v1/grid_weapon_blueprint.rb new file mode 100644 index 0000000..1d1dc9d --- /dev/null +++ b/app/blueprints/api/v1/grid_weapon_blueprint.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module Api + module V1 + class GridWeaponBlueprint < ApiBlueprint + view :nested do + fields :id, :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 + fields :party_id + end + end + end +end diff --git a/app/blueprints/api/v1/job_blueprint.rb b/app/blueprints/api/v1/job_blueprint.rb new file mode 100644 index 0000000..b2299c4 --- /dev/null +++ b/app/blueprints/api/v1/job_blueprint.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Api + module V1 + class JobBlueprint < ApiBlueprint + fields :id, :row, :ml, :order + + field :name do |job| + { + en: job.name_en, + ja: job.name_jp + } + end + + field :proficiency do |job| + [ + job.proficiency1, + job.proficiency2 + ] + end + end + end +end diff --git a/app/blueprints/api/v1/job_skill_blueprint.rb b/app/blueprints/api/v1/job_skill_blueprint.rb new file mode 100644 index 0000000..5b4c86b --- /dev/null +++ b/app/blueprints/api/v1/job_skill_blueprint.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Api + module V1 + class JobSkillBlueprint < ApiBlueprint + fields :id, :slug, :color, :main, :base, :sub, :emp, :order + + association :job, + name: :job, + blueprint: JobBlueprint + + field :name do |skill| + { + en: skill.name_en, + ja: skill.name_jp + } + end + end + end +end diff --git a/app/blueprints/api/v1/party_blueprint.rb b/app/blueprints/api/v1/party_blueprint.rb new file mode 100644 index 0000000..20927a1 --- /dev/null +++ b/app/blueprints/api/v1/party_blueprint.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Api + module V1 + class PartyBlueprint < ApiBlueprint + view :preview do + fields :id, :name, :element, :shortcode, :favorited, :extra, :created_at, :updated_at + + association :raid, + blueprint: RaidBlueprint + + association :job, + blueprint: JobBlueprint + + association :weapons, + blueprint: GridWeaponBlueprint, + view: :nested + end + + view :full do + include_view :preview + fields :description, :extra + + 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 + + association :characters, + blueprint: GridCharacterBlueprint, + view: :nested + + association :summons, + blueprint: GridSummonBlueprint, + view: :nested + end + end + end +end diff --git a/app/blueprints/api/v1/raid_blueprint.rb b/app/blueprints/api/v1/raid_blueprint.rb new file mode 100644 index 0000000..3a83225 --- /dev/null +++ b/app/blueprints/api/v1/raid_blueprint.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Api + module V1 + class RaidBlueprint < ApiBlueprint + fields :id, :slug, :level, :group, :element + field :name do |raid| + { + en: raid.name_en, + ja: raid.name_jp + } + end + end + end +end diff --git a/app/blueprints/api/v1/summon_blueprint.rb b/app/blueprints/api/v1/summon_blueprint.rb new file mode 100644 index 0000000..4173b80 --- /dev/null +++ b/app/blueprints/api/v1/summon_blueprint.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module Api + module V1 + class SummonBlueprint < ApiBlueprint + fields :id, :granblue_id, :element, :rarity, :max_level + + field :name do |w| + { + en: w.name_en, + ja: w.name_jp + } + end + + 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 diff --git a/app/blueprints/api/v1/user_blueprint.rb b/app/blueprints/api/v1/user_blueprint.rb new file mode 100644 index 0000000..4f88e92 --- /dev/null +++ b/app/blueprints/api/v1/user_blueprint.rb @@ -0,0 +1,29 @@ +# 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 + association :parties, + name: :parties, + blueprint: PartyBlueprint, view: :preview, + if: ->(_field_name, user, _options) { user.parties.length.positive? }, + &:parties + end + + view :settings do + fields :email + end + end + end +end diff --git a/app/blueprints/api/v1/weapon_blueprint.rb b/app/blueprints/api/v1/weapon_blueprint.rb new file mode 100644 index 0000000..917c34d --- /dev/null +++ b/app/blueprints/api/v1/weapon_blueprint.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Api + module V1 + class WeaponBlueprint < ApiBlueprint + fields :id, :granblue_id, :element, :proficiency, + :max_level, :max_skill_level, :limit, :rarity, + :series, :ax + + field :name do |w| + { + en: w.name_en, + ja: w.name_jp + } + end + + 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 diff --git a/app/blueprints/api/v1/weapon_key_blueprint.rb b/app/blueprints/api/v1/weapon_key_blueprint.rb new file mode 100644 index 0000000..4a959df --- /dev/null +++ b/app/blueprints/api/v1/weapon_key_blueprint.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module Api + module V1 + class WeaponKeyBlueprint < ApiBlueprint + end + end +end diff --git a/app/models/character.rb b/app/models/character.rb index 631614c..c772471 100644 --- a/app/models/character.rb +++ b/app/models/character.rb @@ -20,6 +20,10 @@ class Character < ApplicationRecord } } + def blueprint + CharacterBlueprint + end + def display_resource(character) character.name_en end diff --git a/app/models/favorite.rb b/app/models/favorite.rb index 13c5992..4c2d235 100644 --- a/app/models/favorite.rb +++ b/app/models/favorite.rb @@ -7,4 +7,8 @@ class Favorite < ApplicationRecord def party Party.find(party_id) end + + def favorite + FavoriteBlueprint + end end diff --git a/app/models/grid_character.rb b/app/models/grid_character.rb index badf5f9..2e3e16b 100644 --- a/app/models/grid_character.rb +++ b/app/models/grid_character.rb @@ -6,4 +6,8 @@ class GridCharacter < ApplicationRecord def character Character.find(character_id) end + + def blueprint + GridCharacterBlueprint + end end diff --git a/app/models/grid_summon.rb b/app/models/grid_summon.rb index 0f95dd8..9857a9b 100644 --- a/app/models/grid_summon.rb +++ b/app/models/grid_summon.rb @@ -6,4 +6,8 @@ class GridSummon < ApplicationRecord def summon Summon.find(summon_id) end + + def blueprint + GridSummonBlueprint + end end diff --git a/app/models/grid_weapon.rb b/app/models/grid_weapon.rb index 295b30c..bd97efb 100644 --- a/app/models/grid_weapon.rb +++ b/app/models/grid_weapon.rb @@ -20,4 +20,8 @@ class GridWeapon < ApplicationRecord weapon_keys end + + def blueprint + GridWeaponBlueprint + end end diff --git a/app/models/job.rb b/app/models/job.rb index 66420a9..beb0ce4 100644 --- a/app/models/job.rb +++ b/app/models/job.rb @@ -8,6 +8,10 @@ class Job < ApplicationRecord class_name: 'Job', optional: true + def blueprint + JobBlueprint + end + def display_resource(job) job.name_en end diff --git a/app/models/job_skill.rb b/app/models/job_skill.rb index b1109ea..9e0bcd3 100644 --- a/app/models/job_skill.rb +++ b/app/models/job_skill.rb @@ -25,6 +25,10 @@ class JobSkill < ApplicationRecord } } + def blueprint + JobSkillBlueprint + end + def display_resource(skill) skill.name_en end diff --git a/app/models/party.rb b/app/models/party.rb index fe2b45e..c90c0c4 100644 --- a/app/models/party.rb +++ b/app/models/party.rb @@ -52,6 +52,10 @@ class Party < ApplicationRecord user.favorite_parties.include? self end + def blueprint + PartyBlueprint + end + private def skills_are_unique diff --git a/app/models/raid.rb b/app/models/raid.rb index 7d4a12b..9163f71 100644 --- a/app/models/raid.rb +++ b/app/models/raid.rb @@ -1,4 +1,7 @@ # frozen_string_literal: true class Raid < ApplicationRecord + def blueprint + RaidBlueprint + end end diff --git a/app/models/summon.rb b/app/models/summon.rb index 775d61d..7efab1b 100644 --- a/app/models/summon.rb +++ b/app/models/summon.rb @@ -20,6 +20,10 @@ class Summon < ApplicationRecord } } + def blueprint + SummonBlueprint + end + def display_resource(summon) summon.name_en end diff --git a/app/models/user.rb b/app/models/user.rb index 44a0e76..215885e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -42,4 +42,8 @@ class User < ApplicationRecord def favorite_parties favorites.map(&:party) end + + def blueprint + UserBlueprint + end end diff --git a/app/models/weapon.rb b/app/models/weapon.rb index 646f82c..ed45010 100644 --- a/app/models/weapon.rb +++ b/app/models/weapon.rb @@ -20,6 +20,10 @@ class Weapon < ApplicationRecord } } + def blueprint + WeaponBlueprint + end + def display_resource(weapon) weapon.name_en end diff --git a/app/models/weapon_key.rb b/app/models/weapon_key.rb index 4615b11..cfce439 100644 --- a/app/models/weapon_key.rb +++ b/app/models/weapon_key.rb @@ -1,4 +1,7 @@ # frozen_string_literal: true class WeaponKey < ApplicationRecord + def blueprint + WeaponKeyBlueprint + end end From 2fe8b8de1a21e3750761f514e366f6bf9851c270 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 15:33:53 -0800 Subject: [PATCH 09/42] Fix Rubocop warnings for arrays --- config/routes.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index f7f94e2..831dbd7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,13 +1,13 @@ Rails.application.routes.draw do use_doorkeeper do - controllers :tokens => 'tokens' + controllers tokens: 'tokens' skip_controllers :applications, :authorized_applications end namespace :api, defaults: { format: :json } do namespace :v1 do - resources :parties, only: [:index, :create, :update, :destroy] - resources :users, only: [:create, :update, :show] + resources :parties, only: %i[index create update destroy] + resources :users, only: %i[create update show] resources :grid_weapons, only: [:update] resources :favorites, only: [:create] From 290099e2f4a271bef89ee999fc15de06f2903406 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 15:34:54 -0800 Subject: [PATCH 10/42] Refactor PartiesController for blueprinter * Refactored and tried to simplify methods in PartiesController * Implemented new error render methods in ApiController * Removed parties/[weapons, summons, characters] routes --- app/blueprints/api/v1/party_blueprint.rb | 41 +++-- app/controllers/api/v1/api_controller.rb | 13 +- app/controllers/api/v1/parties_controller.rb | 156 ++++++++----------- config/routes.rb | 3 - 4 files changed, 107 insertions(+), 106 deletions(-) diff --git a/app/blueprints/api/v1/party_blueprint.rb b/app/blueprints/api/v1/party_blueprint.rb index 20927a1..969760c 100644 --- a/app/blueprints/api/v1/party_blueprint.rb +++ b/app/blueprints/api/v1/party_blueprint.rb @@ -3,8 +3,28 @@ module Api module V1 class PartyBlueprint < ApiBlueprint + identifier :id + + 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 :preview do - fields :id, :name, :element, :shortcode, :favorited, :extra, :created_at, :updated_at + fields :name, :element, :shortcode, :favorited, :extra, :created_at, :updated_at association :raid, blueprint: RaidBlueprint @@ -12,9 +32,7 @@ module Api association :job, blueprint: JobBlueprint - association :weapons, - blueprint: GridWeaponBlueprint, - view: :nested + include_view :weapons end view :full do @@ -30,13 +48,16 @@ module Api } end - association :characters, - blueprint: GridCharacterBlueprint, - view: :nested + include_view :summons + include_view :characters + end - association :summons, - blueprint: GridSummonBlueprint, - view: :nested + view :collection do + include_view :preview + end + + view :destroyed do + fields :name, :description, :created_at, :updated_at end end end diff --git a/app/controllers/api/v1/api_controller.rb b/app/controllers/api/v1/api_controller.rb index e7a7c37..4a14f31 100644 --- a/app/controllers/api/v1/api_controller.rb +++ b/app/controllers/api/v1/api_controller.rb @@ -65,9 +65,16 @@ module Api render action: 'errors', status: :unprocessable_entity end - def render_not_found_response - response = { errors: [{ message: 'Record could not be found.', code: 'not_found' }] } - render 'not_found', status: :not_found + 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(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 diff --git a/app/controllers/api/v1/parties_controller.rb b/app/controllers/api/v1/parties_controller.rb index 5a7d88a..ccf131d 100644 --- a/app/controllers/api/v1/parties_controller.rb +++ b/app/controllers/api/v1/parties_controller.rb @@ -2,6 +2,8 @@ module Api module V1 + PER_PAGE = 15 + class PartiesController < Api::V1::ApiController before_action :set_from_slug, except: %w[create destroy update index favorites] @@ -11,6 +13,7 @@ module Api @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) @@ -21,122 +24,95 @@ module Api @party.user = current_user if current_user - render :show, status: :created if @party.save! + if @party.save! + return render json: PartyBlueprint.render(@party, view: :full, root: :party), + status: :created + end + + render_validation_error_response(@party) end def show - render_not_found_response if @party.nil? + return render json: PartyBlueprint.render(@party, view: :full, root: :party) if @party + + render_not_found_response('project') 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_unauthorized_response if @party.user != current_user - render :update, status: :ok if @party.save! + @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 - @per_page = 15 + conditions = build_conditions(request.params) - now = DateTime.current - unless request.params['recency'].blank? - start_time = - ( - now - request.params['recency'].to_i.seconds - ).to_datetime.beginning_of_day - end + @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 } - 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 + count = Party.where(conditions).count + total_pages = count.to_f / PER_PAGE > 1 ? (count.to_f / PER_PAGE).ceil : 1 - @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 + render json: PartyBlueprint.render(@parties, + view: :collection, + root: :results, + meta: { + total_pages: total_pages, + count: count + }) end def favorites raise Api::V1::UnauthorizedError unless current_user - @per_page = 15 - - now = DateTime.current - unless request.params['recency'].blank? - start_time = - ( - now - params['recency'].to_i.seconds - ).to_datetime.beginning_of_day - end - - 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 = 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 + @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) } - render :all, status: :ok - end + count = Party.joins(:favorites).where(conditions).count + total_pages = count.to_f / PER_PAGE > 1 ? (count.to_f / PER_PAGE).ceil : 1 - 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 + render json: PartyBlueprint.render(@parties, + view: :collection, + root: :results, + meta: { + total_pages: total_pages, + count: count + }) 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 + + { + element: (params['element'] unless params['element'].blank?), + raid: (params['raid'] unless params['raid'].blank?), + created_at: (start_time..now unless params['recency'].blank?), + weapons_count: 5..13 + } + end + def random_string num_chars = 6 o = [('a'..'z'), ('A'..'Z'), (0..9)].map(&:to_a).flatten diff --git a/config/routes.rb b/config/routes.rb index 831dbd7..de3e5f7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -15,9 +15,6 @@ Rails.application.routes.draw do get 'parties/favorites', to: 'parties#favorites' get 'parties/:id', to: 'parties#show' - get 'parties/:id/weapons', to: 'parties#weapons' - get 'parties/:id/summons', to: 'parties#summons' - get 'parties/:id/characters', to: 'parties#characters' put 'parties/:id/jobs', to: 'jobs#update_job' put 'parties/:id/job_skills', to: 'jobs#update_job_skills' From 44e92733d334080702a8989e6c3a45be5b7e1312 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 15:35:05 -0800 Subject: [PATCH 11/42] Refactor RaidsController for blueprinter --- app/controllers/api/v1/raids_controller.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/controllers/api/v1/raids_controller.rb b/app/controllers/api/v1/raids_controller.rb index 6e9e51c..f5b898e 100644 --- a/app/controllers/api/v1/raids_controller.rb +++ b/app/controllers/api/v1/raids_controller.rb @@ -4,8 +4,7 @@ module Api module V1 class RaidsController < Api::V1::ApiController def all - @raids = Raid.all - render :all, status: :ok + render json: RaidBlueprint.render(Raid.all) end end end From f86aa307914d9e5e3cd3679cd9f87d3edbaf041d Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 15:50:06 -0800 Subject: [PATCH 12/42] GranblueError should not require input param --- app/errors/api/v1/granblue_error.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/errors/api/v1/granblue_error.rb b/app/errors/api/v1/granblue_error.rb index dec43a1..e2d0c70 100644 --- a/app/errors/api/v1/granblue_error.rb +++ b/app/errors/api/v1/granblue_error.rb @@ -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 From 5b37e480f8028794c234fb8383d23ff53a548004 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 16:10:53 -0800 Subject: [PATCH 13/42] Refactor FavoritesController for blueprinter --- app/blueprints/api/v1/favorite_blueprint.rb | 26 +++++++++++++++++++ .../api/v1/favorites_controller.rb | 13 ++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 app/blueprints/api/v1/favorite_blueprint.rb diff --git a/app/blueprints/api/v1/favorite_blueprint.rb b/app/blueprints/api/v1/favorite_blueprint.rb new file mode 100644 index 0000000..fc482ee --- /dev/null +++ b/app/blueprints/api/v1/favorite_blueprint.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Api + module V1 + class FavoriteBlueprint < ApiBlueprint + identifier :id + fields :created_at, :updated_at + + association :user, + name: :user, + blueprint: UserBlueprint, + view: :minimal + + association :party, + name: :party, + blueprint: PartyBlueprint, + view: :preview + + view :destroyed do + field :destroyed do + true + end + end + end + end +end diff --git a/app/controllers/api/v1/favorites_controller.rb b/app/controllers/api/v1/favorites_controller.rb index 177f2f2..4f5279b 100644 --- a/app/controllers/api/v1/favorites_controller.rb +++ b/app/controllers/api/v1/favorites_controller.rb @@ -18,14 +18,23 @@ module Api user_id: current_user.id, party_id: party_id }) - render :show, status: :created if @favorite.save! + + if @favorite.save! + return render json: FavoriteBlueprint.render(@favorite, root: :favorite), + status: :created + end + + 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) + render_not_found_response('favorite') unless @favorite + + render_error("Couldn't delete favorite") unless Favorite.destroy(@favorite.id) + render json: FavoriteBlueprint.render(@favorite, root: :favorite, view: :destroyed) end private From af518699275d92c810e2ac5776144f371f099cb1 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 16:20:00 -0800 Subject: [PATCH 14/42] Fix build_conditions method The method of assigning values was assigning nil if the value wasn't present in `params`, which is bad --- app/controllers/api/v1/parties_controller.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/parties_controller.rb b/app/controllers/api/v1/parties_controller.rb index ccf131d..b8b949d 100644 --- a/app/controllers/api/v1/parties_controller.rb +++ b/app/controllers/api/v1/parties_controller.rb @@ -55,6 +55,7 @@ module Api def index conditions = build_conditions(request.params) + ap conditions @parties = Party.where(conditions) .order(created_at: :desc) @@ -105,12 +106,12 @@ module Api .to_datetime.beginning_of_day end - { - element: (params['element'] unless params['element'].blank?), - raid: (params['raid'] unless params['raid'].blank?), - created_at: (start_time..now unless params['recency'].blank?), - weapons_count: 5..13 - } + {}.tap do |hash| + hash[:element] = params['element'] unless params['element'].blank? + hash[:raid] = params['raid'] unless params['raid'].blank? + hash[:created_at] = start_time..now unless params['recency'].blank? + hash[:weapons_count] = 5..13 + end end def random_string From 979d28be759039975f73ba994f9fe33d7c63b20e Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 16:20:04 -0800 Subject: [PATCH 15/42] Update party_blueprint.rb --- app/blueprints/api/v1/party_blueprint.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/blueprints/api/v1/party_blueprint.rb b/app/blueprints/api/v1/party_blueprint.rb index 969760c..d3e9695 100644 --- a/app/blueprints/api/v1/party_blueprint.rb +++ b/app/blueprints/api/v1/party_blueprint.rb @@ -37,6 +37,9 @@ module Api view :full do include_view :preview + include_view :summons + include_view :characters + fields :description, :extra field :job_skills do |job| @@ -47,9 +50,6 @@ module Api '3' => !job.skill3.nil? ? JobSkillBlueprint.render_as_hash(job.skill3) : nil } end - - include_view :summons - include_view :characters end view :collection do From bf04ddcbbad70f0b5b109592a0bc76e6c8f7b6d4 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 19:27:33 -0800 Subject: [PATCH 16/42] Fix GridObject blueprints --- app/blueprints/api/v1/grid_character_blueprint.rb | 12 ++++++++++-- app/blueprints/api/v1/grid_summon_blueprint.rb | 12 ++++++++++-- app/blueprints/api/v1/grid_weapon_blueprint.rb | 12 ++++++++++-- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/app/blueprints/api/v1/grid_character_blueprint.rb b/app/blueprints/api/v1/grid_character_blueprint.rb index 5984c71..f04537e 100644 --- a/app/blueprints/api/v1/grid_character_blueprint.rb +++ b/app/blueprints/api/v1/grid_character_blueprint.rb @@ -3,13 +3,21 @@ module Api module V1 class GridCharacterBlueprint < ApiBlueprint + identifier :id + + view :uncap do + association :party, blueprint: PartyBlueprint + fields :position, :uncap_level + end + view :nested do - fields :id, :position, :uncap_level, :perpetuity + fields :position, :uncap_level, :perpetuity association :character, name: :object, blueprint: CharacterBlueprint end view :full do - fields :party_id + include_view :nested + association :party, blueprint: PartyBlueprint end end end diff --git a/app/blueprints/api/v1/grid_summon_blueprint.rb b/app/blueprints/api/v1/grid_summon_blueprint.rb index ae9c58b..d42920f 100644 --- a/app/blueprints/api/v1/grid_summon_blueprint.rb +++ b/app/blueprints/api/v1/grid_summon_blueprint.rb @@ -3,13 +3,21 @@ module Api module V1 class GridSummonBlueprint < ApiBlueprint + identifier :id + + view :uncap do + association :party, blueprint: PartyBlueprint + fields :position, :uncap_level + end + view :nested do - fields :id, :main, :friend, :position, :uncap_level + fields :main, :friend, :position, :uncap_level association :summon, name: :object, blueprint: SummonBlueprint end view :full do - fields :party_id + include_view :nested + association :party, blueprint: PartyBlueprint end end end diff --git a/app/blueprints/api/v1/grid_weapon_blueprint.rb b/app/blueprints/api/v1/grid_weapon_blueprint.rb index 1d1dc9d..b7e7579 100644 --- a/app/blueprints/api/v1/grid_weapon_blueprint.rb +++ b/app/blueprints/api/v1/grid_weapon_blueprint.rb @@ -3,8 +3,15 @@ module Api module V1 class GridWeaponBlueprint < ApiBlueprint + identifier :id + + view :uncap do + association :party, blueprint: PartyBlueprint + fields :position, :uncap_level + end + view :nested do - fields :id, :mainhand, :position, :uncap_level, :element + fields :mainhand, :position, :uncap_level, :element association :weapon, name: :object, blueprint: WeaponBlueprint association :weapon_keys, @@ -28,7 +35,8 @@ module Api end view :full do - fields :party_id + include_view :nested + association :party, blueprint: PartyBlueprint end end end From 33775539cddba0e7d0d5763c7b4c155dff7f781a Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 19:27:55 -0800 Subject: [PATCH 17/42] Add ConflictBlueprint This should be used for character conflicts (implemented) and weapon conflicts (to-do in a future PR) --- app/blueprints/api/v1/conflict_blueprint.rb | 31 +++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 app/blueprints/api/v1/conflict_blueprint.rb diff --git a/app/blueprints/api/v1/conflict_blueprint.rb b/app/blueprints/api/v1/conflict_blueprint.rb new file mode 100644 index 0000000..d35a1c2 --- /dev/null +++ b/app/blueprints/api/v1/conflict_blueprint.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Api + module V1 + class ConflictBlueprint < ApiBlueprint + field :position do + options[:incoming_position] + end + + view :characters do + field :conflicts do + GridCharacterBlueprint.render_as_hash(options[:conflict_characters]) + end + + field :incoming do + GridCharacterBlueprint.render_as_hash(options[:incoming_character]) + end + end + + view :weapons do + field :conflicts do + GridWeaponBlueprint.render_as_hash(options[:conflict_weapons]) + end + + field :incoming do + GridWeaponBlueprint.render_as_hash(options[:incoming_weapon]) + end + end + end + end +end From 747ffbc4ff25872a1b6b8aa92c8f8c1ae54f0e4a Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 20:39:17 -0800 Subject: [PATCH 18/42] Update GridObject blueprints with view --- app/blueprints/api/v1/grid_character_blueprint.rb | 2 +- app/blueprints/api/v1/grid_summon_blueprint.rb | 2 +- app/blueprints/api/v1/grid_weapon_blueprint.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/blueprints/api/v1/grid_character_blueprint.rb b/app/blueprints/api/v1/grid_character_blueprint.rb index f04537e..544c0f7 100644 --- a/app/blueprints/api/v1/grid_character_blueprint.rb +++ b/app/blueprints/api/v1/grid_character_blueprint.rb @@ -17,7 +17,7 @@ module Api view :full do include_view :nested - association :party, blueprint: PartyBlueprint + association :party, blueprint: PartyBlueprint, view: :preview end end end diff --git a/app/blueprints/api/v1/grid_summon_blueprint.rb b/app/blueprints/api/v1/grid_summon_blueprint.rb index d42920f..161f824 100644 --- a/app/blueprints/api/v1/grid_summon_blueprint.rb +++ b/app/blueprints/api/v1/grid_summon_blueprint.rb @@ -17,7 +17,7 @@ module Api view :full do include_view :nested - association :party, blueprint: PartyBlueprint + association :party, blueprint: PartyBlueprint, view: :preview end end end diff --git a/app/blueprints/api/v1/grid_weapon_blueprint.rb b/app/blueprints/api/v1/grid_weapon_blueprint.rb index b7e7579..df4244d 100644 --- a/app/blueprints/api/v1/grid_weapon_blueprint.rb +++ b/app/blueprints/api/v1/grid_weapon_blueprint.rb @@ -36,7 +36,7 @@ module Api view :full do include_view :nested - association :party, blueprint: PartyBlueprint + association :party, blueprint: PartyBlueprint, view: :preview end end end From a15ba3c376a976f358b3dc231d07074e8d81148e Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 20:40:27 -0800 Subject: [PATCH 19/42] Correct ConflictBlueprint ConflictBlueprint uses `options` to display arbitrary values, but I think those are only available behind conditional statements. This adds those statements and checks if the key that will be used exists on the hash. ConflictBlueprint was also inheriting from ApiBlueprint which requires a real object (with an ID), so instead we inherit from Blueprinter::Base --- app/blueprints/api/v1/conflict_blueprint.rb | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/blueprints/api/v1/conflict_blueprint.rb b/app/blueprints/api/v1/conflict_blueprint.rb index d35a1c2..eccfab1 100644 --- a/app/blueprints/api/v1/conflict_blueprint.rb +++ b/app/blueprints/api/v1/conflict_blueprint.rb @@ -2,28 +2,28 @@ module Api module V1 - class ConflictBlueprint < ApiBlueprint - field :position do + 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 do - GridCharacterBlueprint.render_as_hash(options[:conflict_characters]) + field :conflicts, if: ->(_fn, _obj, options) { options.key?(:conflict_characters) } do |_, options| + GridCharacterBlueprint.render_as_hash(options[:conflict_characters], view: :nested) end - field :incoming do - GridCharacterBlueprint.render_as_hash(options[:incoming_character]) + 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 do - GridWeaponBlueprint.render_as_hash(options[:conflict_weapons]) + field :conflicts, if: ->(_fn, _obj, options) { options.key?(:conflict_weapons) } do |_, options| + GridWeaponBlueprint.render_as_hash(options[:conflict_weapons], view: :nested) end - field :incoming do - GridWeaponBlueprint.render_as_hash(options[:incoming_weapon]) + field :incoming, if: ->(_fn, _obj, options) { options.key?(:incoming_weapon) } do |_, options| + WeaponBlueprint.render_as_hash(options[:incoming_weapon]) end end end From 2a74b8aa4df46d281ecbfc8504b7c0f3194167bb Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 20:53:34 -0800 Subject: [PATCH 20/42] Add minimal view to Party and use in GridObject --- app/blueprints/api/v1/grid_character_blueprint.rb | 4 ++-- app/blueprints/api/v1/grid_summon_blueprint.rb | 4 ++-- app/blueprints/api/v1/grid_weapon_blueprint.rb | 4 ++-- app/blueprints/api/v1/party_blueprint.rb | 5 ++++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/blueprints/api/v1/grid_character_blueprint.rb b/app/blueprints/api/v1/grid_character_blueprint.rb index 544c0f7..2057014 100644 --- a/app/blueprints/api/v1/grid_character_blueprint.rb +++ b/app/blueprints/api/v1/grid_character_blueprint.rb @@ -6,7 +6,7 @@ module Api identifier :id view :uncap do - association :party, blueprint: PartyBlueprint + association :party, blueprint: PartyBlueprint, view: :minimal fields :position, :uncap_level end @@ -17,7 +17,7 @@ module Api view :full do include_view :nested - association :party, blueprint: PartyBlueprint, view: :preview + association :party, blueprint: PartyBlueprint, view: :minimal end end end diff --git a/app/blueprints/api/v1/grid_summon_blueprint.rb b/app/blueprints/api/v1/grid_summon_blueprint.rb index 161f824..31685b5 100644 --- a/app/blueprints/api/v1/grid_summon_blueprint.rb +++ b/app/blueprints/api/v1/grid_summon_blueprint.rb @@ -6,7 +6,7 @@ module Api identifier :id view :uncap do - association :party, blueprint: PartyBlueprint + association :party, blueprint: PartyBlueprint, view: :minimal fields :position, :uncap_level end @@ -17,7 +17,7 @@ module Api view :full do include_view :nested - association :party, blueprint: PartyBlueprint, view: :preview + association :party, blueprint: PartyBlueprint, view: :minimal end end end diff --git a/app/blueprints/api/v1/grid_weapon_blueprint.rb b/app/blueprints/api/v1/grid_weapon_blueprint.rb index df4244d..02ba7cc 100644 --- a/app/blueprints/api/v1/grid_weapon_blueprint.rb +++ b/app/blueprints/api/v1/grid_weapon_blueprint.rb @@ -6,7 +6,7 @@ module Api identifier :id view :uncap do - association :party, blueprint: PartyBlueprint + association :party, blueprint: PartyBlueprint, view: :minimal fields :position, :uncap_level end @@ -36,7 +36,7 @@ module Api view :full do include_view :nested - association :party, blueprint: PartyBlueprint, view: :preview + association :party, blueprint: PartyBlueprint, view: :minimal end end end diff --git a/app/blueprints/api/v1/party_blueprint.rb b/app/blueprints/api/v1/party_blueprint.rb index d3e9695..e0d8f32 100644 --- a/app/blueprints/api/v1/party_blueprint.rb +++ b/app/blueprints/api/v1/party_blueprint.rb @@ -23,7 +23,7 @@ module Api view: :nested end - view :preview do + view :minimal do fields :name, :element, :shortcode, :favorited, :extra, :created_at, :updated_at association :raid, @@ -31,7 +31,10 @@ module Api association :job, blueprint: JobBlueprint + end + view :preview do + include_view :minimal include_view :weapons end From 116ec9dbbcae33d243153d539204801a71ca2b2f Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 20:53:48 -0800 Subject: [PATCH 21/42] Refactor GridObjectControllers to use blueprinter --- .../api/v1/grid_characters_controller.rb | 34 +++++++++---------- .../api/v1/grid_summons_controller.rb | 13 +++---- .../api/v1/grid_weapons_controller.rb | 23 +++++++------ 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/app/controllers/api/v1/grid_characters_controller.rb b/app/controllers/api/v1/grid_characters_controller.rb index 4848d8b..a581b2f 100644 --- a/app/controllers/api/v1/grid_characters_controller.rb +++ b/app/controllers/api/v1/grid_characters_controller.rb @@ -27,24 +27,23 @@ module Api # a decision. # 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 :conflict, status: :ok + 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 + 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)) + 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 @@ -70,20 +69,21 @@ module Api 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! + 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 update_uncap_level - @character = GridCharacter.find(character_params[:id]) + character = GridCharacter.find(character_params[:id]) - render_unauthorized_response if current_user && (@character.party.user != current_user) + render_unauthorized_response if current_user && (character.party.user != current_user) - @character.uncap_level = character_params[:uncap_level] - render :show, status: :ok if @character.save! + character.uncap_level = character_params[:uncap_level] + render json: GridCharacterBlueprint.render(character, view: :uncap) if character.save! end + # TODO: Implement removing characters def destroy; end private diff --git a/app/controllers/api/v1/grid_summons_controller.rb b/app/controllers/api/v1/grid_summons_controller.rb index 3db26e7..335839e 100644 --- a/app/controllers/api/v1/grid_summons_controller.rb +++ b/app/controllers/api/v1/grid_summons_controller.rb @@ -16,19 +16,20 @@ module Api GridSummon.destroy(grid_summon.id) end - @summon = GridSummon.create!(summon_params.merge(party_id: party.id, summon_id: canonical_summon.id)) - render :show, status: :created if @summon.save! + 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 def update_uncap_level - @summon = GridSummon.find(summon_params[:id]) + summon = GridSummon.find(summon_params[:id]) - render_unauthorized_response if current_user && (@summon.party.user != current_user) + 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! + summon.uncap_level = summon_params[:uncap_level] + render json: GridSummonBlueprint.render(summon, view: :uncap) if summon.save! end + # TODO: Implement removing summons def destroy; end private diff --git a/app/controllers/api/v1/grid_weapons_controller.rb b/app/controllers/api/v1/grid_weapons_controller.rb index 07cefdb..56c0f25 100644 --- a/app/controllers/api/v1/grid_weapons_controller.rb +++ b/app/controllers/api/v1/grid_weapons_controller.rb @@ -11,44 +11,45 @@ module Api render_unauthorized_response if current_user && (party.user != current_user) - if grid_weapon = GridWeapon.where( + if (grid_weapon = GridWeapon.where( party_id: party.id, position: weapon_params[:position] - ).first + ).first) GridWeapon.destroy(grid_weapon.id) end - @weapon = GridWeapon.create!(weapon_params.merge(party_id: party.id, weapon_id: canonical_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 + if weapon.position == -1 + party.element = weapon.weapon.element party.save! end - render :show, status: :created if @weapon.save! + render json: GridWeaponBlueprint.render(weapon, view: :full), status: :created if weapon.save! end def update render_unauthorized_response if current_user && (@weapon.party.user != current_user) - ap weapon_params - # TODO: Server-side validation of weapon mods # We don't want someone modifying the JSON and adding # keys to weapons that cannot have them # Maybe we make methods on the model to validate for us somehow - render :update, status: :ok if @weapon.update(weapon_params) + render json: GridWeaponBlueprint.render(@weapon, view: :nested) if @weapon.update(weapon_params) end + # TODO: Implement removing characters + def destroy; end + def update_uncap_level @weapon = GridWeapon.find(weapon_params[:id]) - render_unauthorized_response if current_user && (party.user != current_user) + render_unauthorized_response if current_user && (@weapon.party.user != current_user) @weapon.uncap_level = weapon_params[:uncap_level] - render :show, status: :ok if @weapon.save! + render json: GridWeaponBlueprint.render(@weapon, view: :uncap), status: :created if @weapon.save! end private From 3b6edfae5d65e07b64726b9e193389629d33da98 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 21:04:42 -0800 Subject: [PATCH 22/42] Update WeaponKey output for blueprinter --- app/blueprints/api/v1/weapon_key_blueprint.rb | 8 ++++++++ app/controllers/api/v1/weapon_keys_controller.rb | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/blueprints/api/v1/weapon_key_blueprint.rb b/app/blueprints/api/v1/weapon_key_blueprint.rb index 4a959df..64ed12f 100644 --- a/app/blueprints/api/v1/weapon_key_blueprint.rb +++ b/app/blueprints/api/v1/weapon_key_blueprint.rb @@ -3,6 +3,14 @@ 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 diff --git a/app/controllers/api/v1/weapon_keys_controller.rb b/app/controllers/api/v1/weapon_keys_controller.rb index 8bdcaaa..f9ba041 100644 --- a/app/controllers/api/v1/weapon_keys_controller.rb +++ b/app/controllers/api/v1/weapon_keys_controller.rb @@ -10,7 +10,7 @@ module Api conditions[:group] = request.params['group'] unless request.params['group'].blank? @keys = WeaponKey.where(conditions) - render :all, status: :ok + render json: WeaponKeyBlueprint.render(@keys) end end end From 349c42f83915f09fe3ac845429139e9f3d96ce9b Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 21:07:26 -0800 Subject: [PATCH 23/42] Update blueprints to remove id field or identifier This is built into ApiBlueprint --- app/blueprints/api/v1/character_blueprint.rb | 6 +++--- app/blueprints/api/v1/favorite_blueprint.rb | 5 ++--- app/blueprints/api/v1/grid_character_blueprint.rb | 2 -- app/blueprints/api/v1/grid_summon_blueprint.rb | 2 -- app/blueprints/api/v1/grid_weapon_blueprint.rb | 2 -- app/blueprints/api/v1/job_blueprint.rb | 4 ++-- app/blueprints/api/v1/job_skill_blueprint.rb | 12 ++++++------ app/blueprints/api/v1/party_blueprint.rb | 2 -- app/blueprints/api/v1/raid_blueprint.rb | 3 ++- app/blueprints/api/v1/summon_blueprint.rb | 4 ++-- app/blueprints/api/v1/weapon_blueprint.rb | 8 ++++---- 11 files changed, 21 insertions(+), 29 deletions(-) diff --git a/app/blueprints/api/v1/character_blueprint.rb b/app/blueprints/api/v1/character_blueprint.rb index 1fe220e..d47bde7 100644 --- a/app/blueprints/api/v1/character_blueprint.rb +++ b/app/blueprints/api/v1/character_blueprint.rb @@ -3,9 +3,6 @@ module Api module V1 class CharacterBlueprint < ApiBlueprint - fields :id, :granblue_id, :character_id, :rarity, - :element, :gender, :special - field :name do |w| { en: w.name_en, @@ -13,6 +10,9 @@ module Api } end + fields :granblue_id, :character_id, :rarity, + :element, :gender, :special + field :uncap do |w| { flb: w.flb, diff --git a/app/blueprints/api/v1/favorite_blueprint.rb b/app/blueprints/api/v1/favorite_blueprint.rb index fc482ee..60aa642 100644 --- a/app/blueprints/api/v1/favorite_blueprint.rb +++ b/app/blueprints/api/v1/favorite_blueprint.rb @@ -3,9 +3,6 @@ module Api module V1 class FavoriteBlueprint < ApiBlueprint - identifier :id - fields :created_at, :updated_at - association :user, name: :user, blueprint: UserBlueprint, @@ -16,6 +13,8 @@ module Api blueprint: PartyBlueprint, view: :preview + fields :created_at, :updated_at + view :destroyed do field :destroyed do true diff --git a/app/blueprints/api/v1/grid_character_blueprint.rb b/app/blueprints/api/v1/grid_character_blueprint.rb index 2057014..c3aff00 100644 --- a/app/blueprints/api/v1/grid_character_blueprint.rb +++ b/app/blueprints/api/v1/grid_character_blueprint.rb @@ -3,8 +3,6 @@ module Api module V1 class GridCharacterBlueprint < ApiBlueprint - identifier :id - view :uncap do association :party, blueprint: PartyBlueprint, view: :minimal fields :position, :uncap_level diff --git a/app/blueprints/api/v1/grid_summon_blueprint.rb b/app/blueprints/api/v1/grid_summon_blueprint.rb index 31685b5..af2cec6 100644 --- a/app/blueprints/api/v1/grid_summon_blueprint.rb +++ b/app/blueprints/api/v1/grid_summon_blueprint.rb @@ -3,8 +3,6 @@ module Api module V1 class GridSummonBlueprint < ApiBlueprint - identifier :id - view :uncap do association :party, blueprint: PartyBlueprint, view: :minimal fields :position, :uncap_level diff --git a/app/blueprints/api/v1/grid_weapon_blueprint.rb b/app/blueprints/api/v1/grid_weapon_blueprint.rb index 02ba7cc..0c28a26 100644 --- a/app/blueprints/api/v1/grid_weapon_blueprint.rb +++ b/app/blueprints/api/v1/grid_weapon_blueprint.rb @@ -3,8 +3,6 @@ module Api module V1 class GridWeaponBlueprint < ApiBlueprint - identifier :id - view :uncap do association :party, blueprint: PartyBlueprint, view: :minimal fields :position, :uncap_level diff --git a/app/blueprints/api/v1/job_blueprint.rb b/app/blueprints/api/v1/job_blueprint.rb index b2299c4..319a62b 100644 --- a/app/blueprints/api/v1/job_blueprint.rb +++ b/app/blueprints/api/v1/job_blueprint.rb @@ -3,8 +3,6 @@ module Api module V1 class JobBlueprint < ApiBlueprint - fields :id, :row, :ml, :order - field :name do |job| { en: job.name_en, @@ -18,6 +16,8 @@ module Api job.proficiency2 ] end + + fields :row, :ml, :order end end end diff --git a/app/blueprints/api/v1/job_skill_blueprint.rb b/app/blueprints/api/v1/job_skill_blueprint.rb index 5b4c86b..b6b79b1 100644 --- a/app/blueprints/api/v1/job_skill_blueprint.rb +++ b/app/blueprints/api/v1/job_skill_blueprint.rb @@ -3,18 +3,18 @@ module Api module V1 class JobSkillBlueprint < ApiBlueprint - fields :id, :slug, :color, :main, :base, :sub, :emp, :order - - association :job, - name: :job, - blueprint: JobBlueprint - 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 diff --git a/app/blueprints/api/v1/party_blueprint.rb b/app/blueprints/api/v1/party_blueprint.rb index e0d8f32..63789c1 100644 --- a/app/blueprints/api/v1/party_blueprint.rb +++ b/app/blueprints/api/v1/party_blueprint.rb @@ -3,8 +3,6 @@ module Api module V1 class PartyBlueprint < ApiBlueprint - identifier :id - view :weapons do association :weapons, blueprint: GridWeaponBlueprint, diff --git a/app/blueprints/api/v1/raid_blueprint.rb b/app/blueprints/api/v1/raid_blueprint.rb index 3a83225..295c09a 100644 --- a/app/blueprints/api/v1/raid_blueprint.rb +++ b/app/blueprints/api/v1/raid_blueprint.rb @@ -3,13 +3,14 @@ module Api module V1 class RaidBlueprint < ApiBlueprint - fields :id, :slug, :level, :group, :element field :name do |raid| { en: raid.name_en, ja: raid.name_jp } end + + fields :slug, :level, :group, :element end end end diff --git a/app/blueprints/api/v1/summon_blueprint.rb b/app/blueprints/api/v1/summon_blueprint.rb index 4173b80..3db846d 100644 --- a/app/blueprints/api/v1/summon_blueprint.rb +++ b/app/blueprints/api/v1/summon_blueprint.rb @@ -3,8 +3,6 @@ module Api module V1 class SummonBlueprint < ApiBlueprint - fields :id, :granblue_id, :element, :rarity, :max_level - field :name do |w| { en: w.name_en, @@ -12,6 +10,8 @@ module Api } end + fields :granblue_id, :element, :rarity, :max_level + field :uncap do |w| { flb: w.flb, diff --git a/app/blueprints/api/v1/weapon_blueprint.rb b/app/blueprints/api/v1/weapon_blueprint.rb index 917c34d..5d715da 100644 --- a/app/blueprints/api/v1/weapon_blueprint.rb +++ b/app/blueprints/api/v1/weapon_blueprint.rb @@ -3,10 +3,6 @@ module Api module V1 class WeaponBlueprint < ApiBlueprint - fields :id, :granblue_id, :element, :proficiency, - :max_level, :max_skill_level, :limit, :rarity, - :series, :ax - field :name do |w| { en: w.name_en, @@ -14,6 +10,10 @@ module Api } end + fields :granblue_id, :element, :proficiency, + :max_level, :max_skill_level, :limit, :rarity, + :series, :ax + field :uncap do |w| { flb: w.flb, From 9a27ac853d826d785bb71cccf0c812af8c084084 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 21:46:35 -0800 Subject: [PATCH 24/42] Update JobsController and JobSkillsController for blueprinter --- app/blueprints/api/v1/party_blueprint.rb | 27 ++++++++++++------- .../api/v1/job_skills_controller.rb | 10 +++---- app/controllers/api/v1/jobs_controller.rb | 7 +++-- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/app/blueprints/api/v1/party_blueprint.rb b/app/blueprints/api/v1/party_blueprint.rb index 63789c1..baac168 100644 --- a/app/blueprints/api/v1/party_blueprint.rb +++ b/app/blueprints/api/v1/party_blueprint.rb @@ -21,6 +21,17 @@ module Api 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 @@ -31,6 +42,12 @@ module Api blueprint: JobBlueprint end + view :jobs do + association :job, + blueprint: JobBlueprint + include_view :job_skills + end + view :preview do include_view :minimal include_view :weapons @@ -40,17 +57,9 @@ module Api include_view :preview include_view :summons include_view :characters + include_view :job_skills fields :description, :extra - - 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 :collection do diff --git a/app/controllers/api/v1/job_skills_controller.rb b/app/controllers/api/v1/job_skills_controller.rb index d5a5864..bedc216 100644 --- a/app/controllers/api/v1/job_skills_controller.rb +++ b/app/controllers/api/v1/job_skills_controller.rb @@ -4,15 +4,13 @@ module Api module V1 class JobSkillsController < Api::V1::ApiController def all - @skills = JobSkill.all - render :all, status: :ok + render json: JobSkillBlueprint.render(JobSkill.all) end def job - job = Job.find(params[:id]) - - @skills = JobSkill.where(job: job).or(JobSkill.where(sub: true)) - render :all, status: :ok + @skills = JobSkill.where(job: Job.find(params[:id])) + .or(JobSkill.where(sub: true)) + render json: JobSkillBlueprint.render(@skills) end end end diff --git a/app/controllers/api/v1/jobs_controller.rb b/app/controllers/api/v1/jobs_controller.rb index 7fbe75b..f404337 100644 --- a/app/controllers/api/v1/jobs_controller.rb +++ b/app/controllers/api/v1/jobs_controller.rb @@ -6,8 +6,7 @@ module Api before_action :set, only: %w[update_job update_job_skills] def all - @jobs = Job.all - render :all, status: :ok + render json: JobBlueprint.render(Job.all) end def update_job @@ -28,7 +27,7 @@ module Api @party[key] = nil if @party[key] && mismatched_skill(@party.job, JobSkill.find(@party[key])) end - render :update, status: :ok if @party.save! + render json: PartyBlueprint.render(@party, view: :jobs) if @party.save! end def update_job_skills @@ -63,7 +62,7 @@ module Api @party.attributes = new_skill_ids end - render :update, status: :ok if @party.save! + render json: PartyBlueprint.render(@party, view: :jobs) if @party.save! end private From 89e666219a5a7db6ecf980ac83050bc189b8371d Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 22:10:31 -0800 Subject: [PATCH 25/42] Update SearchController for blueprinter --- app/controllers/api/v1/search_controller.rb | 146 ++++++++++++-------- 1 file changed, 86 insertions(+), 60 deletions(-) diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb index e40f394..acf9893 100644 --- a/app/controllers/api/v1/search_controller.rb +++ b/app/controllers/api/v1/search_controller.rb @@ -2,6 +2,8 @@ module Api module V1 + PER_PAGE = 10 + class SearchController < Api::V1::ApiController def characters filters = search_params[:filters] @@ -22,18 +24,23 @@ module Api # 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 + 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 - @characters = @characters.paginate(page: search_params[:page], per_page: 10) + count = characters.length + paginated = characters.paginate(page: search_params[:page], per_page: PER_PAGE) + + render json: CharacterBlueprint.render(paginated, meta: { + count: count, + total_pages: total_pages(count) + }) end def weapons @@ -51,18 +58,23 @@ module Api 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' - Weapon.jp_search(search_params[:query]).where(conditions) - else - Weapon.en_search(search_params[:query]).where(conditions) - end - else - Weapon.where(conditions) - end + weapons = if search_params[:query].present? && search_params[:query].length >= 2 + if locale == 'ja' + Weapon.jp_search(search_params[:query]).where(conditions) + else + Weapon.en_search(search_params[:query]).where(conditions) + end + else + Weapon.where(conditions) + end - @count = @weapons.length - @weapons = @weapons.paginate(page: search_params[:page], per_page: 10) + count = weapons.length + paginated = weapons.paginate(page: search_params[:page], per_page: PER_PAGE) + + render json: WeaponBlueprint.render(paginated, meta: { + count: count, + total_pages: total_pages(count) + }) end def summons @@ -75,18 +87,23 @@ module Api 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 + 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 - @summons = @summons.paginate(page: search_params[:page], per_page: 10) + count = summons.length + paginated = summons.paginate(page: search_params[:page], per_page: PER_PAGE) + + render json: SummonBlueprint.render(paginated, meta: { + count: count, + total_pages: total_pages(count) + }) end def job_skills @@ -113,38 +130,47 @@ module Api 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 + 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) + count = skills.length + paginated = skills.paginate(page: search_params[:page], per_page: PER_PAGE) + + render json: JobSkillBlueprint.render(paginated, meta: { + count: count, + total_pages: total_pages(count) + }) end private + def total_pages(count) + count.to_f / PER_PAGE > 1 ? (count.to_f / PER_PAGE).ceil : 1 + end + # Specify whitelisted properties that can be modified. def search_params params.require(:search).permit! From 41c031092e9dc29bb6d03f7be5b06589a83606f6 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 22:10:35 -0800 Subject: [PATCH 26/42] Update weapon_keys_controller.rb --- app/controllers/api/v1/weapon_keys_controller.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/weapon_keys_controller.rb b/app/controllers/api/v1/weapon_keys_controller.rb index f9ba041..1d7e261 100644 --- a/app/controllers/api/v1/weapon_keys_controller.rb +++ b/app/controllers/api/v1/weapon_keys_controller.rb @@ -4,13 +4,15 @@ module Api module V1 class 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? + 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 - @keys = WeaponKey.where(conditions) - render json: WeaponKeyBlueprint.render(@keys) + render json: WeaponKeyBlueprint.render( + WeaponKey.where(conditions) + ) end end end From 5c97488a20d02b09e1bf78c640e0a6c1e554657c Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 23:13:19 -0800 Subject: [PATCH 27/42] Update UsersController to use blueprinter --- app/blueprints/api/v1/empty_blueprint.rb | 15 ++++ app/blueprints/api/v1/user_blueprint.rb | 14 +-- app/controllers/api/v1/users_controller.rb | 100 +++++++++++---------- 3 files changed, 76 insertions(+), 53 deletions(-) create mode 100644 app/blueprints/api/v1/empty_blueprint.rb diff --git a/app/blueprints/api/v1/empty_blueprint.rb b/app/blueprints/api/v1/empty_blueprint.rb new file mode 100644 index 0000000..6709741 --- /dev/null +++ b/app/blueprints/api/v1/empty_blueprint.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Api + module V1 + class EmptyBlueprint < Blueprinter::Base + field :email_available, if: ->(_field_name, _empty, options) { options.key?(:email) } do |_, options| + User.where('email = ?', options[:email]).count.zero? + end + + field :username_available, if: ->(_field_name, _empty, options) { options.key?(:username) } do |_, options| + User.where('username = ?', options[:username]).count.zero? + end + end + end +end diff --git a/app/blueprints/api/v1/user_blueprint.rb b/app/blueprints/api/v1/user_blueprint.rb index 4f88e92..dace3a7 100644 --- a/app/blueprints/api/v1/user_blueprint.rb +++ b/app/blueprints/api/v1/user_blueprint.rb @@ -14,11 +14,15 @@ module Api end view :profile do - association :parties, - name: :parties, - blueprint: PartyBlueprint, view: :preview, - if: ->(_field_name, user, _options) { user.parties.length.positive? }, - &:parties + 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 diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb index 98a4ebc..c2ca040 100644 --- a/app/controllers/api/v1/users_controller.rb +++ b/app/controllers/api/v1/users_controller.rb @@ -2,6 +2,8 @@ module Api module V1 + PER_PAGE = 15 + class UsersController < Api::V1::ApiController class ForbiddenError < StandardError; end @@ -9,86 +11,88 @@ module Api before_action :set_by_id, only: %w[info update] def create - @user = User.new(user_params) + user = User.new(user_params) token = Doorkeeper::AccessToken.create!( application_id: nil, - resource_owner_id: @user.id, + resource_owner_id: user.id, expires_in: 30.days, scopes: 'public' ).token - return unless @user.save! + if user.save! + return render json: UserBlueprint.render({ + id: user.id, + username: user.username, + token: token + }, + view: :token), + status: :created + end - @presenter = { - user_id: @user.id, - username: @user.username, - token: token - } - - render :create, status: :created + render_validation_error_response(@user) end def update - render :info, status: :ok if @user.update(user_params) + render json: UserBlueprint.render(@user, view: :minimal) if @user.update(user_params) end def info - render :info, status: :ok + render json: UserBlueprint.render(@user, view: :minimal) end def show - if @user - @per_page = 15 + render_not_found_response('user') unless @user - now = DateTime.current - unless request.params['recency'].blank? - start_time = (now - params['recency'].to_i.seconds).to_datetime.beginning_of_day - end + conditions = build_conditions(request.params) + conditions[:user_id] = @user.id - 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 do |party| - party.favorited = current_user ? party.is_favorited(current_user) : false - end - @count = Party.where(conditions).count - else - render_not_found_response + 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 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 def check_email - @available = if params[:email].present? - User.where('email = ?', params[:email]).count.zero? - else - false - end - - render :available + render json: EmptyBlueprint.render_as_json(nil, email: params[:email]) end def check_username - @available = if params[:username].present? - User.where('username = ?', params[:username]).count.zero? - else - false - end - - render :available + render json: EmptyBlueprint.render_as_json(nil, username: params[:username]) end def destroy; 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..now unless params['recency'].blank? + end + end + # Specify whitelisted properties that can be modified. def set @user = User.where('username = ?', params[:id]).first From 415ef39158ec863b2979cc45b00764605b6906ad Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 23:15:17 -0800 Subject: [PATCH 28/42] Add per_page to methods that return collections --- app/controllers/api/v1/parties_controller.rb | 6 ++++-- app/controllers/api/v1/search_controller.rb | 12 ++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/parties_controller.rb b/app/controllers/api/v1/parties_controller.rb index b8b949d..fe32077 100644 --- a/app/controllers/api/v1/parties_controller.rb +++ b/app/controllers/api/v1/parties_controller.rb @@ -69,8 +69,9 @@ module Api view: :collection, root: :results, meta: { + count: count, total_pages: total_pages, - count: count + per_page: PER_PAGE }) end @@ -93,8 +94,9 @@ module Api view: :collection, root: :results, meta: { + count: count, total_pages: total_pages, - count: count + per_page: PER_PAGE }) end diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb index acf9893..0eeedff 100644 --- a/app/controllers/api/v1/search_controller.rb +++ b/app/controllers/api/v1/search_controller.rb @@ -39,7 +39,8 @@ module Api render json: CharacterBlueprint.render(paginated, meta: { count: count, - total_pages: total_pages(count) + total_pages: total_pages(count), + per_page: PER_PAGE }) end @@ -73,7 +74,8 @@ module Api render json: WeaponBlueprint.render(paginated, meta: { count: count, - total_pages: total_pages(count) + total_pages: total_pages(count), + per_page: PER_PAGE }) end @@ -102,7 +104,8 @@ module Api render json: SummonBlueprint.render(paginated, meta: { count: count, - total_pages: total_pages(count) + total_pages: total_pages(count), + per_page: PER_PAGE }) end @@ -161,7 +164,8 @@ module Api render json: JobSkillBlueprint.render(paginated, meta: { count: count, - total_pages: total_pages(count) + total_pages: total_pages(count), + per_page: PER_PAGE }) end From c0be03dcb61e04d00046696ab5817dcb3377b63f Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 23:28:54 -0800 Subject: [PATCH 29/42] Finish migrating ApiController error methods --- app/blueprints/api/v1/error_blueprint.rb | 4 ++++ app/controllers/api/v1/api_controller.rb | 7 ++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/blueprints/api/v1/error_blueprint.rb b/app/blueprints/api/v1/error_blueprint.rb index 92a9580..78a431a 100644 --- a/app/blueprints/api/v1/error_blueprint.rb +++ b/app/blueprints/api/v1/error_blueprint.rb @@ -10,6 +10,10 @@ module Api 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 diff --git a/app/controllers/api/v1/api_controller.rb b/app/controllers/api/v1/api_controller.rb index 4a14f31..a1ae703 100644 --- a/app/controllers/api/v1/api_controller.rb +++ b/app/controllers/api/v1/api_controller.rb @@ -61,8 +61,8 @@ module Api end def render_unprocessable_entity_response(exception) - @exception = exception - render action: 'errors', status: :unprocessable_entity + render json: ErrorBlueprint.render_as_json(nil, exception: exception), + status: :unprocessable_entity end def render_validation_error_response(object) @@ -78,7 +78,8 @@ module Api end def render_unauthorized_response - render action: 'errors', status: :unauthorized + render json: ErrorBlueprint.render_as_json(nil), + status: :unauthorized end private From 7ddc9162165241a030c4f725e21903503a27833d Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Wed, 21 Dec 2022 23:29:20 -0800 Subject: [PATCH 30/42] Remove rabl views Our work here is done --- app/views/api/v1/api/errors.json.rabl | 18 ----- app/views/api/v1/api/not_found.json.rabl | 8 --- app/views/api/v1/characters/base.json.rabl | 68 ------------------- app/views/api/v1/favorites/base.json.rabl | 3 - .../api/v1/favorites/destroyed.json.rabl | 5 -- app/views/api/v1/favorites/show.json.rabl | 3 - .../api/v1/grid_characters/base.json.rabl | 9 --- .../api/v1/grid_characters/conflict.json.rabl | 14 ---- .../api/v1/grid_characters/show.json.rabl | 3 - app/views/api/v1/grid_summons/base.json.rabl | 10 --- app/views/api/v1/grid_summons/show.json.rabl | 3 - app/views/api/v1/grid_weapons/base.json.rabl | 27 -------- app/views/api/v1/grid_weapons/show.json.rabl | 3 - .../api/v1/grid_weapons/update.json.rabl | 3 - app/views/api/v1/job_skills/all.json.rabl | 3 - app/views/api/v1/job_skills/base.json.rabl | 10 --- app/views/api/v1/jobs/all.json.rabl | 3 - app/views/api/v1/jobs/base.json.rabl | 17 ----- app/views/api/v1/jobs/update.json.rabl | 20 ------ app/views/api/v1/parties/all.json.rabl | 11 --- app/views/api/v1/parties/base.json.rabl | 47 ------------- app/views/api/v1/parties/characters.json.rabl | 15 ---- app/views/api/v1/parties/destroyed.json.rabl | 5 -- app/views/api/v1/parties/show.json.rabl | 3 - app/views/api/v1/parties/summons.json.rabl | 15 ---- app/views/api/v1/parties/update.json.rabl | 20 ------ app/views/api/v1/parties/weapons.json.rabl | 19 ------ app/views/api/v1/raids/all.json.rabl | 3 - app/views/api/v1/raids/base.json.rabl | 10 --- app/views/api/v1/search/characters.json.rabl | 11 --- app/views/api/v1/search/job_skills.json.rabl | 11 --- app/views/api/v1/search/summons.json.rabl | 11 --- app/views/api/v1/search/weapons.json.rabl | 11 --- app/views/api/v1/summons/base.json.rabl | 39 ----------- app/views/api/v1/users/available.json.rabl | 5 -- app/views/api/v1/users/base.json.rabl | 15 ---- app/views/api/v1/users/create.json.rabl | 9 --- app/views/api/v1/users/info.json.rabl | 3 - app/views/api/v1/users/show.json.rabl | 19 ------ app/views/api/v1/weapon_keys/all.json.rabl | 3 - app/views/api/v1/weapon_keys/base.json.rabl | 10 --- app/views/api/v1/weapons/base.json.rabl | 44 ------------ 42 files changed, 569 deletions(-) delete mode 100644 app/views/api/v1/api/errors.json.rabl delete mode 100644 app/views/api/v1/api/not_found.json.rabl delete mode 100644 app/views/api/v1/characters/base.json.rabl delete mode 100644 app/views/api/v1/favorites/base.json.rabl delete mode 100644 app/views/api/v1/favorites/destroyed.json.rabl delete mode 100644 app/views/api/v1/favorites/show.json.rabl delete mode 100644 app/views/api/v1/grid_characters/base.json.rabl delete mode 100644 app/views/api/v1/grid_characters/conflict.json.rabl delete mode 100644 app/views/api/v1/grid_characters/show.json.rabl delete mode 100644 app/views/api/v1/grid_summons/base.json.rabl delete mode 100644 app/views/api/v1/grid_summons/show.json.rabl delete mode 100644 app/views/api/v1/grid_weapons/base.json.rabl delete mode 100644 app/views/api/v1/grid_weapons/show.json.rabl delete mode 100644 app/views/api/v1/grid_weapons/update.json.rabl delete mode 100644 app/views/api/v1/job_skills/all.json.rabl delete mode 100644 app/views/api/v1/job_skills/base.json.rabl delete mode 100644 app/views/api/v1/jobs/all.json.rabl delete mode 100644 app/views/api/v1/jobs/base.json.rabl delete mode 100644 app/views/api/v1/jobs/update.json.rabl delete mode 100644 app/views/api/v1/parties/all.json.rabl delete mode 100644 app/views/api/v1/parties/base.json.rabl delete mode 100644 app/views/api/v1/parties/characters.json.rabl delete mode 100644 app/views/api/v1/parties/destroyed.json.rabl delete mode 100644 app/views/api/v1/parties/show.json.rabl delete mode 100644 app/views/api/v1/parties/summons.json.rabl delete mode 100644 app/views/api/v1/parties/update.json.rabl delete mode 100644 app/views/api/v1/parties/weapons.json.rabl delete mode 100644 app/views/api/v1/raids/all.json.rabl delete mode 100644 app/views/api/v1/raids/base.json.rabl delete mode 100644 app/views/api/v1/search/characters.json.rabl delete mode 100644 app/views/api/v1/search/job_skills.json.rabl delete mode 100644 app/views/api/v1/search/summons.json.rabl delete mode 100644 app/views/api/v1/search/weapons.json.rabl delete mode 100644 app/views/api/v1/summons/base.json.rabl delete mode 100644 app/views/api/v1/users/available.json.rabl delete mode 100644 app/views/api/v1/users/base.json.rabl delete mode 100644 app/views/api/v1/users/create.json.rabl delete mode 100644 app/views/api/v1/users/info.json.rabl delete mode 100644 app/views/api/v1/users/show.json.rabl delete mode 100644 app/views/api/v1/weapon_keys/all.json.rabl delete mode 100644 app/views/api/v1/weapon_keys/base.json.rabl delete mode 100644 app/views/api/v1/weapons/base.json.rabl diff --git a/app/views/api/v1/api/errors.json.rabl b/app/views/api/v1/api/errors.json.rabl deleted file mode 100644 index 78c87ff..0000000 --- a/app/views/api/v1/api/errors.json.rabl +++ /dev/null @@ -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 diff --git a/app/views/api/v1/api/not_found.json.rabl b/app/views/api/v1/api/not_found.json.rabl deleted file mode 100644 index 9bc7b58..0000000 --- a/app/views/api/v1/api/not_found.json.rabl +++ /dev/null @@ -1,8 +0,0 @@ -object false - -node(:errors) do - { - 'message': "Record could not be found.", - 'code': 'not_found' - } -end \ No newline at end of file diff --git a/app/views/api/v1/characters/base.json.rabl b/app/views/api/v1/characters/base.json.rabl deleted file mode 100644 index 47976a3..0000000 --- a/app/views/api/v1/characters/base.json.rabl +++ /dev/null @@ -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 diff --git a/app/views/api/v1/favorites/base.json.rabl b/app/views/api/v1/favorites/base.json.rabl deleted file mode 100644 index e7525b8..0000000 --- a/app/views/api/v1/favorites/base.json.rabl +++ /dev/null @@ -1,3 +0,0 @@ -object :favorite - -attributes :id, :user_id, :party_id, :created_at, :updated_at diff --git a/app/views/api/v1/favorites/destroyed.json.rabl b/app/views/api/v1/favorites/destroyed.json.rabl deleted file mode 100644 index f791b2f..0000000 --- a/app/views/api/v1/favorites/destroyed.json.rabl +++ /dev/null @@ -1,5 +0,0 @@ -object false - -node :destroyed do - true -end \ No newline at end of file diff --git a/app/views/api/v1/favorites/show.json.rabl b/app/views/api/v1/favorites/show.json.rabl deleted file mode 100644 index 2b85585..0000000 --- a/app/views/api/v1/favorites/show.json.rabl +++ /dev/null @@ -1,3 +0,0 @@ -object @favorite - -extends 'api/v1/favorites/base' \ No newline at end of file diff --git a/app/views/api/v1/grid_characters/base.json.rabl b/app/views/api/v1/grid_characters/base.json.rabl deleted file mode 100644 index 74e9ec1..0000000 --- a/app/views/api/v1/grid_characters/base.json.rabl +++ /dev/null @@ -1,9 +0,0 @@ -attributes :id, - :party_id, - :position, - :uncap_level, - :perpetuity - -node :object do |c| - partial("characters/base", :object => c.character) -end \ No newline at end of file diff --git a/app/views/api/v1/grid_characters/conflict.json.rabl b/app/views/api/v1/grid_characters/conflict.json.rabl deleted file mode 100644 index e67e0fc..0000000 --- a/app/views/api/v1/grid_characters/conflict.json.rabl +++ /dev/null @@ -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 - \ No newline at end of file diff --git a/app/views/api/v1/grid_characters/show.json.rabl b/app/views/api/v1/grid_characters/show.json.rabl deleted file mode 100644 index ca858d8..0000000 --- a/app/views/api/v1/grid_characters/show.json.rabl +++ /dev/null @@ -1,3 +0,0 @@ -object @character - -extends 'api/v1/grid_characters/base' \ No newline at end of file diff --git a/app/views/api/v1/grid_summons/base.json.rabl b/app/views/api/v1/grid_summons/base.json.rabl deleted file mode 100644 index 8a20ce9..0000000 --- a/app/views/api/v1/grid_summons/base.json.rabl +++ /dev/null @@ -1,10 +0,0 @@ -attributes :id, - :party_id, - :main, - :friend, - :position, - :uncap_level - -node :object do |s| - partial('summons/base', :object => s.summon) -end \ No newline at end of file diff --git a/app/views/api/v1/grid_summons/show.json.rabl b/app/views/api/v1/grid_summons/show.json.rabl deleted file mode 100644 index 07c4dcb..0000000 --- a/app/views/api/v1/grid_summons/show.json.rabl +++ /dev/null @@ -1,3 +0,0 @@ -object @summon - -extends 'api/v1/grid_summons/base' \ No newline at end of file diff --git a/app/views/api/v1/grid_weapons/base.json.rabl b/app/views/api/v1/grid_weapons/base.json.rabl deleted file mode 100644 index 36b5c87..0000000 --- a/app/views/api/v1/grid_weapons/base.json.rabl +++ /dev/null @@ -1,27 +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 \ No newline at end of file diff --git a/app/views/api/v1/grid_weapons/show.json.rabl b/app/views/api/v1/grid_weapons/show.json.rabl deleted file mode 100644 index cd450b3..0000000 --- a/app/views/api/v1/grid_weapons/show.json.rabl +++ /dev/null @@ -1,3 +0,0 @@ -object @weapon - -extends 'api/v1/grid_weapons/base' \ No newline at end of file diff --git a/app/views/api/v1/grid_weapons/update.json.rabl b/app/views/api/v1/grid_weapons/update.json.rabl deleted file mode 100644 index cd450b3..0000000 --- a/app/views/api/v1/grid_weapons/update.json.rabl +++ /dev/null @@ -1,3 +0,0 @@ -object @weapon - -extends 'api/v1/grid_weapons/base' \ No newline at end of file diff --git a/app/views/api/v1/job_skills/all.json.rabl b/app/views/api/v1/job_skills/all.json.rabl deleted file mode 100644 index ba30a1c..0000000 --- a/app/views/api/v1/job_skills/all.json.rabl +++ /dev/null @@ -1,3 +0,0 @@ -collection @skills, object_root: false - -extends 'job_skills/base' diff --git a/app/views/api/v1/job_skills/base.json.rabl b/app/views/api/v1/job_skills/base.json.rabl deleted file mode 100644 index 03c6f1e..0000000 --- a/app/views/api/v1/job_skills/base.json.rabl +++ /dev/null @@ -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 diff --git a/app/views/api/v1/jobs/all.json.rabl b/app/views/api/v1/jobs/all.json.rabl deleted file mode 100644 index f39bf78..0000000 --- a/app/views/api/v1/jobs/all.json.rabl +++ /dev/null @@ -1,3 +0,0 @@ -collection @jobs, object_root: false - -extends 'jobs/base' diff --git a/app/views/api/v1/jobs/base.json.rabl b/app/views/api/v1/jobs/base.json.rabl deleted file mode 100644 index c806683..0000000 --- a/app/views/api/v1/jobs/base.json.rabl +++ /dev/null @@ -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 \ No newline at end of file diff --git a/app/views/api/v1/jobs/update.json.rabl b/app/views/api/v1/jobs/update.json.rabl deleted file mode 100644 index 6cb851f..0000000 --- a/app/views/api/v1/jobs/update.json.rabl +++ /dev/null @@ -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 diff --git a/app/views/api/v1/parties/all.json.rabl b/app/views/api/v1/parties/all.json.rabl deleted file mode 100644 index 44d8477..0000000 --- a/app/views/api/v1/parties/all.json.rabl +++ /dev/null @@ -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? diff --git a/app/views/api/v1/parties/base.json.rabl b/app/views/api/v1/parties/base.json.rabl deleted file mode 100644 index 364c711..0000000 --- a/app/views/api/v1/parties/base.json.rabl +++ /dev/null @@ -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 diff --git a/app/views/api/v1/parties/characters.json.rabl b/app/views/api/v1/parties/characters.json.rabl deleted file mode 100644 index e19cb56..0000000 --- a/app/views/api/v1/parties/characters.json.rabl +++ /dev/null @@ -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 diff --git a/app/views/api/v1/parties/destroyed.json.rabl b/app/views/api/v1/parties/destroyed.json.rabl deleted file mode 100644 index f791b2f..0000000 --- a/app/views/api/v1/parties/destroyed.json.rabl +++ /dev/null @@ -1,5 +0,0 @@ -object false - -node :destroyed do - true -end \ No newline at end of file diff --git a/app/views/api/v1/parties/show.json.rabl b/app/views/api/v1/parties/show.json.rabl deleted file mode 100644 index 88809bc..0000000 --- a/app/views/api/v1/parties/show.json.rabl +++ /dev/null @@ -1,3 +0,0 @@ -object @party - -extends 'api/v1/parties/base' \ No newline at end of file diff --git a/app/views/api/v1/parties/summons.json.rabl b/app/views/api/v1/parties/summons.json.rabl deleted file mode 100644 index d823f06..0000000 --- a/app/views/api/v1/parties/summons.json.rabl +++ /dev/null @@ -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 diff --git a/app/views/api/v1/parties/update.json.rabl b/app/views/api/v1/parties/update.json.rabl deleted file mode 100644 index 6cb851f..0000000 --- a/app/views/api/v1/parties/update.json.rabl +++ /dev/null @@ -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 diff --git a/app/views/api/v1/parties/weapons.json.rabl b/app/views/api/v1/parties/weapons.json.rabl deleted file mode 100644 index 3722385..0000000 --- a/app/views/api/v1/parties/weapons.json.rabl +++ /dev/null @@ -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 diff --git a/app/views/api/v1/raids/all.json.rabl b/app/views/api/v1/raids/all.json.rabl deleted file mode 100644 index b6abde3..0000000 --- a/app/views/api/v1/raids/all.json.rabl +++ /dev/null @@ -1,3 +0,0 @@ -collection @raids - -extends 'raids/base' diff --git a/app/views/api/v1/raids/base.json.rabl b/app/views/api/v1/raids/base.json.rabl deleted file mode 100644 index 362a5df..0000000 --- a/app/views/api/v1/raids/base.json.rabl +++ /dev/null @@ -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 \ No newline at end of file diff --git a/app/views/api/v1/search/characters.json.rabl b/app/views/api/v1/search/characters.json.rabl deleted file mode 100644 index ab551fa..0000000 --- a/app/views/api/v1/search/characters.json.rabl +++ /dev/null @@ -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? diff --git a/app/views/api/v1/search/job_skills.json.rabl b/app/views/api/v1/search/job_skills.json.rabl deleted file mode 100644 index 100cca8..0000000 --- a/app/views/api/v1/search/job_skills.json.rabl +++ /dev/null @@ -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? diff --git a/app/views/api/v1/search/summons.json.rabl b/app/views/api/v1/search/summons.json.rabl deleted file mode 100644 index 073eb1e..0000000 --- a/app/views/api/v1/search/summons.json.rabl +++ /dev/null @@ -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? diff --git a/app/views/api/v1/search/weapons.json.rabl b/app/views/api/v1/search/weapons.json.rabl deleted file mode 100644 index b759323..0000000 --- a/app/views/api/v1/search/weapons.json.rabl +++ /dev/null @@ -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? diff --git a/app/views/api/v1/summons/base.json.rabl b/app/views/api/v1/summons/base.json.rabl deleted file mode 100644 index 3811753..0000000 --- a/app/views/api/v1/summons/base.json.rabl +++ /dev/null @@ -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 \ No newline at end of file diff --git a/app/views/api/v1/users/available.json.rabl b/app/views/api/v1/users/available.json.rabl deleted file mode 100644 index 4efcddb..0000000 --- a/app/views/api/v1/users/available.json.rabl +++ /dev/null @@ -1,5 +0,0 @@ -object false - -node(:available) { - @available -} \ No newline at end of file diff --git a/app/views/api/v1/users/base.json.rabl b/app/views/api/v1/users/base.json.rabl deleted file mode 100644 index 642c3f8..0000000 --- a/app/views/api/v1/users/base.json.rabl +++ /dev/null @@ -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 \ No newline at end of file diff --git a/app/views/api/v1/users/create.json.rabl b/app/views/api/v1/users/create.json.rabl deleted file mode 100644 index cea7c27..0000000 --- a/app/views/api/v1/users/create.json.rabl +++ /dev/null @@ -1,9 +0,0 @@ -object false - -node(:user) { - @presenter -} unless @user.blank? - -node(:error) { - @error -} unless @error.blank? diff --git a/app/views/api/v1/users/info.json.rabl b/app/views/api/v1/users/info.json.rabl deleted file mode 100644 index b10685a..0000000 --- a/app/views/api/v1/users/info.json.rabl +++ /dev/null @@ -1,3 +0,0 @@ -object @user - -extends 'api/v1/users/base' \ No newline at end of file diff --git a/app/views/api/v1/users/show.json.rabl b/app/views/api/v1/users/show.json.rabl deleted file mode 100644 index 9a729da..0000000 --- a/app/views/api/v1/users/show.json.rabl +++ /dev/null @@ -1,19 +0,0 @@ -object false - -node :user do - partial('users/base', object: @user) -end - -child :parties do - 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 do - partial('parties/base', object: @parties) - end unless @parties.empty? -end \ No newline at end of file diff --git a/app/views/api/v1/weapon_keys/all.json.rabl b/app/views/api/v1/weapon_keys/all.json.rabl deleted file mode 100644 index f631ea6..0000000 --- a/app/views/api/v1/weapon_keys/all.json.rabl +++ /dev/null @@ -1,3 +0,0 @@ -collection @keys - -extends 'weapon_keys/base' diff --git a/app/views/api/v1/weapon_keys/base.json.rabl b/app/views/api/v1/weapon_keys/base.json.rabl deleted file mode 100644 index 033be8e..0000000 --- a/app/views/api/v1/weapon_keys/base.json.rabl +++ /dev/null @@ -1,10 +0,0 @@ -object :weapon_key - -attributes :id, :series, :slot, :group, :order - -node :name do |k| - { - :en => k.name_en, - :ja => k.name_jp - } -end \ No newline at end of file diff --git a/app/views/api/v1/weapons/base.json.rabl b/app/views/api/v1/weapons/base.json.rabl deleted file mode 100644 index 05b1bc5..0000000 --- a/app/views/api/v1/weapons/base.json.rabl +++ /dev/null @@ -1,44 +0,0 @@ -object :weapon - -attributes :id, - :granblue_id, - :element, - :proficiency, - :max_level, - :max_skill_level, - :limit, - :rarity, - :series, - :ax - -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 \ No newline at end of file From c5391a6683572ce78d7526d63c55692435673ef8 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Thu, 22 Dec 2022 00:44:39 -0800 Subject: [PATCH 31/42] Fix bug where `now` wasn't replaced --- app/controllers/api/v1/parties_controller.rb | 2 +- app/controllers/api/v1/users_controller.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/parties_controller.rb b/app/controllers/api/v1/parties_controller.rb index fe32077..d97b96f 100644 --- a/app/controllers/api/v1/parties_controller.rb +++ b/app/controllers/api/v1/parties_controller.rb @@ -111,7 +111,7 @@ module Api {}.tap do |hash| hash[:element] = params['element'] unless params['element'].blank? hash[:raid] = params['raid'] unless params['raid'].blank? - hash[:created_at] = start_time..now unless params['recency'].blank? + hash[:created_at] = start_time..DateTime.current unless params['recency'].blank? hash[:weapons_count] = 5..13 end end diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb index c2ca040..121c721 100644 --- a/app/controllers/api/v1/users_controller.rb +++ b/app/controllers/api/v1/users_controller.rb @@ -89,7 +89,7 @@ module Api {}.tap do |hash| hash[:element] = params['element'] unless params['element'].blank? hash[:raid] = params['raid'] unless params['raid'].blank? - hash[:created_at] = start_time..now unless params['recency'].blank? + hash[:created_at] = start_time..DateTime.current unless params['recency'].blank? end end From a397fc722d4ea11b3311322b337268e4ac76e5c2 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Thu, 22 Dec 2022 01:01:03 -0800 Subject: [PATCH 32/42] Pass root when rendering in SearchController --- app/controllers/api/v1/search_controller.rb | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb index 0eeedff..13b6757 100644 --- a/app/controllers/api/v1/search_controller.rb +++ b/app/controllers/api/v1/search_controller.rb @@ -37,7 +37,9 @@ module Api count = characters.length paginated = characters.paginate(page: search_params[:page], per_page: PER_PAGE) - render json: CharacterBlueprint.render(paginated, meta: { + render json: CharacterBlueprint.render(paginated, + root: :results, + meta: { count: count, total_pages: total_pages(count), per_page: PER_PAGE @@ -72,7 +74,9 @@ module Api count = weapons.length paginated = weapons.paginate(page: search_params[:page], per_page: PER_PAGE) - render json: WeaponBlueprint.render(paginated, meta: { + render json: WeaponBlueprint.render(paginated, + root: :results, + meta: { count: count, total_pages: total_pages(count), per_page: PER_PAGE @@ -102,7 +106,9 @@ module Api count = summons.length paginated = summons.paginate(page: search_params[:page], per_page: PER_PAGE) - render json: SummonBlueprint.render(paginated, meta: { + render json: SummonBlueprint.render(paginated, + root: :results, + meta: { count: count, total_pages: total_pages(count), per_page: PER_PAGE @@ -162,7 +168,9 @@ module Api count = skills.length paginated = skills.paginate(page: search_params[:page], per_page: PER_PAGE) - render json: JobSkillBlueprint.render(paginated, meta: { + render json: JobSkillBlueprint.render(paginated, + root: :results, + meta: { count: count, total_pages: total_pages(count), per_page: PER_PAGE From 153d36be5a476ed981cbb67abc5bd0291b374521 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Thu, 22 Dec 2022 01:40:02 -0800 Subject: [PATCH 33/42] We need to include the User in the Party --- app/blueprints/api/v1/party_blueprint.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/blueprints/api/v1/party_blueprint.rb b/app/blueprints/api/v1/party_blueprint.rb index baac168..db539fd 100644 --- a/app/blueprints/api/v1/party_blueprint.rb +++ b/app/blueprints/api/v1/party_blueprint.rb @@ -40,6 +40,10 @@ module Api association :job, blueprint: JobBlueprint + + association :user, + blueprint: UserBlueprint, + view: :minimal end view :jobs do From e91e1664a61568b351814b802cf1fb08c60de78e Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Thu, 22 Dec 2022 18:12:34 -0800 Subject: [PATCH 34/42] Update blueprint for availability endpoints --- app/blueprints/api/v1/empty_blueprint.rb | 12 ++++++------ app/controllers/api/v1/users_controller.rb | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/blueprints/api/v1/empty_blueprint.rb b/app/blueprints/api/v1/empty_blueprint.rb index 6709741..ad8b861 100644 --- a/app/blueprints/api/v1/empty_blueprint.rb +++ b/app/blueprints/api/v1/empty_blueprint.rb @@ -3,12 +3,12 @@ module Api module V1 class EmptyBlueprint < Blueprinter::Base - field :email_available, if: ->(_field_name, _empty, options) { options.key?(:email) } do |_, options| - User.where('email = ?', options[:email]).count.zero? - end - - field :username_available, if: ->(_field_name, _empty, options) { options.key?(:username) } do |_, options| - User.where('username = ?', options[:username]).count.zero? + 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 diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb index 121c721..fdab8b0 100644 --- a/app/controllers/api/v1/users_controller.rb +++ b/app/controllers/api/v1/users_controller.rb @@ -69,11 +69,11 @@ module Api end def check_email - render json: EmptyBlueprint.render_as_json(nil, email: params[:email]) + render json: EmptyBlueprint.render_as_json(nil, email: params[:email], availability: true) end def check_username - render json: EmptyBlueprint.render_as_json(nil, username: params[:username]) + render json: EmptyBlueprint.render_as_json(nil, username: params[:username], availability: true) end def destroy; end From 041f8ee189345888f3b02e9dad90b6d74580ee5e Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Thu, 22 Dec 2022 18:12:47 -0800 Subject: [PATCH 35/42] Fix errors with error handling --- app/controllers/api/v1/api_controller.rb | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/v1/api_controller.rb b/app/controllers/api/v1/api_controller.rb index a1ae703..2aceddc 100644 --- a/app/controllers/api/v1/api_controller.rb +++ b/app/controllers/api/v1/api_controller.rb @@ -9,7 +9,7 @@ module Api ##### 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::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 @@ -25,7 +25,7 @@ module Api ##### Hooks before_action :current_user - before_action :set_default_content_type + before_action :default_content_type ##### Responders respond_to :json @@ -41,14 +41,14 @@ module Api end # Set the response content-type - def set_content_type(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 set_default_content_type - set_content_type('application/javascript; charset=utf-8') + def default_content_type + content_type('application/javascript; charset=utf-8') end ### Error response methods @@ -70,6 +70,14 @@ module Api 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", From b7a537f540a435be74ac6aee9ae63c1f1a7cab53 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Thu, 22 Dec 2022 21:27:38 -0800 Subject: [PATCH 36/42] Fix token generation on signup --- app/controllers/api/v1/users_controller.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb index fdab8b0..267e23f 100644 --- a/app/controllers/api/v1/users_controller.rb +++ b/app/controllers/api/v1/users_controller.rb @@ -13,14 +13,14 @@ module Api def create user = User.new(user_params) - token = Doorkeeper::AccessToken.create!( - application_id: nil, - resource_owner_id: user.id, - expires_in: 30.days, - scopes: 'public' - ).token - if user.save! + token = Doorkeeper::AccessToken.create!( + application_id: nil, + resource_owner_id: user.id, + expires_in: 30.days, + scopes: 'public' + ).token + return render json: UserBlueprint.render({ id: user.id, username: user.username, From 8c1d51fb4f1ffa993b7565aeb92578828e1bd36f Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Thu, 22 Dec 2022 23:26:23 -0800 Subject: [PATCH 37/42] Updated getting skills assignable to a job This endpoint isn't used though --- app/controllers/api/v1/job_skills_controller.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/controllers/api/v1/job_skills_controller.rb b/app/controllers/api/v1/job_skills_controller.rb index bedc216..8b466a1 100644 --- a/app/controllers/api/v1/job_skills_controller.rb +++ b/app/controllers/api/v1/job_skills_controller.rb @@ -8,8 +8,7 @@ module Api end def job - @skills = JobSkill.where(job: Job.find(params[:id])) - .or(JobSkill.where(sub: true)) + @skills = JobSkill.where('job_id != ? AND emp = ?', params[:id], true) render json: JobSkillBlueprint.render(@skills) end end From 874c20245dc288891b0bfd76af09ad60431dde51 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Thu, 22 Dec 2022 23:27:24 -0800 Subject: [PATCH 38/42] Refined selecting skills based on job * Bugfix: You can now select a third subskill on Rows 1, 2 and 3 * Edgecase: When switching from a Row 1, 2 or 3 class to Row 4, 5 or EX2, the third EMP skill set is removed --- app/controllers/api/v1/jobs_controller.rb | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/v1/jobs_controller.rb b/app/controllers/api/v1/jobs_controller.rb index f404337..2bf21a0 100644 --- a/app/controllers/api/v1/jobs_controller.rb +++ b/app/controllers/api/v1/jobs_controller.rb @@ -13,6 +13,7 @@ module Api raise NoJobProvidedError unless job_params[:job_id].present? # 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) @@ -27,6 +28,13 @@ module Api @party[key] = nil if @party[key] && mismatched_skill(@party.job, JobSkill.find(@party[key])) end + # Remove extra subskills if necessary + if %w[1 2 3].include?(old_job.row) && + %w[4 5 ex2].include?(job.row) && + @party.skill1.sub && @party.skill2.sub && @party.skill3.sub + @party['skill3_id'] = nil + end + render json: PartyBlueprint.render(@party, view: :jobs) if @party.save! end @@ -122,16 +130,15 @@ module Api end def can_add_skill_of_type(skills, position, type) - if skills.values.compact.length.positive? + 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) } - - sum + 1 <= max_skill_of_type - else - true + return sum + 1 <= max_skill_of_type end + + true end def mismatched_skill(job, skill) From a837210029de028de6ae2b96ba0a3f8e087c477b Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Thu, 22 Dec 2022 23:27:46 -0800 Subject: [PATCH 39/42] Removed current job's subskills from search --- app/controllers/api/v1/search_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb index 13b6757..a383525 100644 --- a/app/controllers/api/v1/search_controller.rb +++ b/app/controllers/api/v1/search_controller.rb @@ -147,6 +147,7 @@ module Api JobSkill.method("#{locale}_search").call(search_params[:query]) .where(conditions) .where(sub: true) + .where.not(job: job.id) ) else JobSkill.all @@ -156,6 +157,7 @@ module Api JobSkill.all .where(conditions) .where(sub: true) + .where.not(job: job.id) ) .or( JobSkill.all From 464fe2f1aae6c37a59b9ed92e4c75bfd8558d865 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Thu, 22 Dec 2022 23:41:04 -0800 Subject: [PATCH 40/42] Update output for GridObjects when uncapping --- app/controllers/api/v1/grid_characters_controller.rb | 4 +++- app/controllers/api/v1/grid_summons_controller.rb | 4 +++- app/controllers/api/v1/grid_weapons_controller.rb | 11 +++++++---- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/grid_characters_controller.rb b/app/controllers/api/v1/grid_characters_controller.rb index a581b2f..31674cd 100644 --- a/app/controllers/api/v1/grid_characters_controller.rb +++ b/app/controllers/api/v1/grid_characters_controller.rb @@ -80,7 +80,9 @@ module Api render_unauthorized_response if current_user && (character.party.user != current_user) character.uncap_level = character_params[:uncap_level] - render json: GridCharacterBlueprint.render(character, view: :uncap) if character.save! + return unless character.save! + + render json: GridCharacterBlueprint.render(character, view: :nested, root: :grid_character) end # TODO: Implement removing characters diff --git a/app/controllers/api/v1/grid_summons_controller.rb b/app/controllers/api/v1/grid_summons_controller.rb index 335839e..cf9ea7d 100644 --- a/app/controllers/api/v1/grid_summons_controller.rb +++ b/app/controllers/api/v1/grid_summons_controller.rb @@ -26,7 +26,9 @@ module Api render_unauthorized_response if current_user && (summon.party.user != current_user) summon.uncap_level = summon_params[:uncap_level] - render json: GridSummonBlueprint.render(summon, view: :uncap) if summon.save! + return unless summon.save! + + render json: GridSummonBlueprint.render(summon, view: :nested, root: :grid_summon) end # TODO: Implement removing summons diff --git a/app/controllers/api/v1/grid_weapons_controller.rb b/app/controllers/api/v1/grid_weapons_controller.rb index 56c0f25..3d21caf 100644 --- a/app/controllers/api/v1/grid_weapons_controller.rb +++ b/app/controllers/api/v1/grid_weapons_controller.rb @@ -44,12 +44,15 @@ module Api def destroy; end def update_uncap_level - @weapon = GridWeapon.find(weapon_params[:id]) + weapon = GridWeapon.find(weapon_params[:id]) - render_unauthorized_response if current_user && (@weapon.party.user != current_user) + render_unauthorized_response if current_user && (weapon.party.user != current_user) - @weapon.uncap_level = weapon_params[:uncap_level] - render json: GridWeaponBlueprint.render(@weapon, view: :uncap), status: :created if @weapon.save! + weapon.uncap_level = weapon_params[:uncap_level] + return unless weapon.save! + + render json: GridWeaponBlueprint.render(weapon, view: :nested, root: :grid_weapon), + status: :created end private From 8b69a44d83f127bb1de57c09fbbe9964f260f20b Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Fri, 23 Dec 2022 15:42:46 -0800 Subject: [PATCH 41/42] Allow unsetting of jobs Unsetting a job also removes all of its skills --- app/controllers/api/v1/jobs_controller.rb | 47 +++++++++++++---------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/app/controllers/api/v1/jobs_controller.rb b/app/controllers/api/v1/jobs_controller.rb index 2bf21a0..f345464 100644 --- a/app/controllers/api/v1/jobs_controller.rb +++ b/app/controllers/api/v1/jobs_controller.rb @@ -10,29 +10,36 @@ module Api end def update_job - raise NoJobProvidedError unless job_params[:job_id].present? + 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) - # 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) + # Update the party + ap job + @party.job = job + main_skills.each_with_index do |skill, index| + @party["skill#{index}_id"] = skill.id + end - # 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 - # 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 %w[1 2 3].include?(old_job.row) && - %w[4 5 ex2].include?(job.row) && - @party.skill1.sub && @party.skill2.sub && @party.skill3.sub - @party['skill3_id'] = nil + # 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.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! From 13dae817379f96ed2b2b2dd02a1236839f763b6c Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Fri, 23 Dec 2022 15:49:30 -0800 Subject: [PATCH 42/42] Fix bug preventing selecting Row IV, V and EXII --- app/controllers/api/v1/jobs_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/jobs_controller.rb b/app/controllers/api/v1/jobs_controller.rb index f345464..db75319 100644 --- a/app/controllers/api/v1/jobs_controller.rb +++ b/app/controllers/api/v1/jobs_controller.rb @@ -17,7 +17,6 @@ module Api main_skills = JobSkill.where(job: job.id, main: true) # Update the party - ap job @party.job = job main_skills.each_with_index do |skill, index| @party["skill#{index}_id"] = skill.id @@ -32,6 +31,7 @@ module Api 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