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