There was a bug that prevented users from deleting parties with remixes, because the source party reference was not being nulled. We fixed that with `dependent: :nullify` but also added a boolean key to the parties database to track if a party is a remix or not. This way, if a party is flagged as a remix but the source party is null, we know that the original party was deleted and can message this on the frontend.
276 lines
10 KiB
Ruby
276 lines
10 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
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]
|
|
before_action :authorize, only: %w[update destroy]
|
|
|
|
MAX_CHARACTERS = 5
|
|
MAX_SUMMONS = 8
|
|
MAX_WEAPONS = 13
|
|
|
|
DEFAULT_MIN_CHARACTERS = 3
|
|
DEFAULT_MIN_SUMMONS = 2
|
|
DEFAULT_MIN_WEAPONS = 5
|
|
|
|
DEFAULT_MAX_CLEAR_TIME = 5400
|
|
|
|
def create
|
|
party = Party.new
|
|
party.user = current_user if current_user
|
|
party.attributes = party_params if party_params
|
|
|
|
# unless party_params.empty?
|
|
# party.attributes = party_params
|
|
#
|
|
# # TODO: Extract this into a different method
|
|
# job = Job.find(party_params['job_id']) if party_params['job_id'].present?
|
|
# if job
|
|
# job_skills = JobSkill.where(job: job.id, main: true)
|
|
# job_skills.each_with_index do |skill, index|
|
|
# party["skill#{index}_id"] = skill.id
|
|
# end
|
|
# end
|
|
# end
|
|
|
|
if party.save!
|
|
return render json: PartyBlueprint.render(party, view: :created, root: :party),
|
|
status: :created
|
|
end
|
|
|
|
render_validation_error_response(@party)
|
|
end
|
|
|
|
def show
|
|
return render json: PartyBlueprint.render(@party, view: :full, root: :party) if @party
|
|
|
|
render_not_found_response('project')
|
|
end
|
|
|
|
def update
|
|
@party.attributes = party_params.except(:skill1_id, :skill2_id, :skill3_id)
|
|
|
|
# TODO: Validate accessory with job
|
|
|
|
return render json: PartyBlueprint.render(@party, view: :full, root: :party) if @party.save
|
|
|
|
render_validation_error_response(@party)
|
|
end
|
|
|
|
def destroy
|
|
return render json: PartyBlueprint.render(@party, view: :destroyed, root: :checkin) if @party.destroy
|
|
end
|
|
|
|
def remix
|
|
new_party = @party.amoeba_dup
|
|
new_party.attributes = {
|
|
user: current_user,
|
|
name: remixed_name(@party.name),
|
|
source_party: @party,
|
|
remix: true
|
|
}
|
|
|
|
new_party.local_id = party_params[:local_id] if !party_params.nil?
|
|
|
|
if new_party.save
|
|
render json: PartyBlueprint.render(new_party, view: :created, root: :party,
|
|
meta: { remix: true })
|
|
else
|
|
render_validation_error_response(new_party)
|
|
end
|
|
end
|
|
|
|
def index
|
|
conditions = build_conditions
|
|
|
|
@parties = Party.joins(:weapons)
|
|
.group('parties.id')
|
|
.having('count(distinct grid_weapons.weapon_id) > 2')
|
|
.where(conditions)
|
|
.where(name_quality)
|
|
.where(user_quality)
|
|
.where(original)
|
|
.order(created_at: :desc)
|
|
.paginate(page: request.params[:page], per_page: COLLECTION_PER_PAGE)
|
|
.each { |party| party.favorited = current_user ? party.is_favorited(current_user) : false }
|
|
|
|
count = Party.where(conditions).count
|
|
total_pages = count.to_f / COLLECTION_PER_PAGE > 1 ? (count.to_f / COLLECTION_PER_PAGE).ceil : 1
|
|
|
|
render json: PartyBlueprint.render(@parties,
|
|
view: :collection,
|
|
root: :results,
|
|
meta: {
|
|
count: count,
|
|
total_pages: total_pages,
|
|
per_page: COLLECTION_PER_PAGE
|
|
})
|
|
end
|
|
|
|
def favorites
|
|
raise Api::V1::UnauthorizedError unless current_user
|
|
|
|
conditions = build_conditions
|
|
conditions[:favorites] = { user_id: current_user.id }
|
|
|
|
@parties = Party.joins(:favorites)
|
|
.where(conditions)
|
|
.where(name_quality)
|
|
.where(user_quality)
|
|
.where(original)
|
|
.order('favorites.created_at DESC')
|
|
.paginate(page: request.params[:page], per_page: COLLECTION_PER_PAGE)
|
|
.each { |party| party.favorited = party.is_favorited(current_user) }
|
|
|
|
count = Party.joins(:favorites).where(conditions).count
|
|
total_pages = count.to_f / COLLECTION_PER_PAGE > 1 ? (count.to_f / COLLECTION_PER_PAGE).ceil : 1
|
|
|
|
render json: PartyBlueprint.render(@parties,
|
|
view: :collection,
|
|
root: :results,
|
|
meta: {
|
|
count: count,
|
|
total_pages: total_pages,
|
|
per_page: COLLECTION_PER_PAGE
|
|
})
|
|
end
|
|
|
|
private
|
|
|
|
def authorize
|
|
render_unauthorized_response if @party.user != current_user || @party.edit_key != edit_key
|
|
end
|
|
|
|
def build_conditions
|
|
params = request.params
|
|
|
|
unless params['recency'].blank?
|
|
start_time = (DateTime.current - params['recency'].to_i.seconds)
|
|
.to_datetime.beginning_of_day
|
|
end
|
|
|
|
min_characters_count = params['characters_count'].blank? ? DEFAULT_MIN_CHARACTERS : params['characters_count'].to_i
|
|
min_summons_count = params['summons_count'].blank? ? DEFAULT_MIN_SUMMONS : params['summons_count'].to_i
|
|
min_weapons_count = params['weapons_count'].blank? ? DEFAULT_MIN_WEAPONS : params['weapons_count'].to_i
|
|
max_clear_time = params['max_clear_time'].blank? ? DEFAULT_MAX_CLEAR_TIME : params['max_clear_time'].to_i
|
|
|
|
{}.tap do |hash|
|
|
# Basic filters
|
|
hash[:element] = params['element'].to_i unless params['element'].blank?
|
|
hash[:raid] = params['raid'] unless params['raid'].blank?
|
|
hash[:created_at] = start_time..DateTime.current unless params['recency'].blank?
|
|
|
|
# Advanced filters: Team parameters
|
|
hash[:full_auto] = params['full_auto'].to_i unless params['full_auto'].blank? || params['full_auto'].to_i == -1
|
|
hash[:auto_guard] = params['auto_guard'].to_i unless params['auto_guard'].blank? || params['auto_guard'].to_i == -1
|
|
hash[:charge_attack] = params['charge_attack'].to_i unless params['charge_attack'].blank? || params['charge_attack'].to_i == -1
|
|
|
|
# Turn count of 0 will not be displayed, so disallow on the frontend or set default to 1
|
|
# How do we do the same for button count since that can reasonably be 1?
|
|
# hash[:turn_count] = params['turn_count'].to_i unless params['turn_count'].blank? || params['turn_count'].to_i <= 0
|
|
# hash[:button_count] = params['button_count'].to_i unless params['button_count'].blank?
|
|
# hash[:clear_time] = 0..max_clear_time
|
|
|
|
# Advanced filters: Object counts
|
|
hash[:characters_count] = min_characters_count..MAX_CHARACTERS
|
|
hash[:summons_count] = min_summons_count..MAX_SUMMONS
|
|
hash[:weapons_count] = min_weapons_count..MAX_WEAPONS
|
|
end
|
|
end
|
|
|
|
def original
|
|
"source_party_id IS NULL" unless request.params['original'].blank? || request.params['original'] == "false"
|
|
end
|
|
|
|
def user_quality
|
|
"user_id IS NOT NULL" unless request.params[:user_quality].blank? || request.params[:user_quality] == "false"
|
|
end
|
|
|
|
def name_quality
|
|
low_quality = [
|
|
"Untitled",
|
|
"Remix of Untitled",
|
|
"Remix of Remix of Untitled",
|
|
"Remix of Remix of Remix of Untitled",
|
|
"Remix of Remix of Remix of Remix of Untitled",
|
|
"Remix of Remix of Remix of Remix of Remix of Untitled",
|
|
"無題",
|
|
"無題のリミックス",
|
|
"無題のリミックスのリミックス",
|
|
"無題のリミックスのリミックスのリミックス",
|
|
"無題のリミックスのリミックスのリミックスのリミックス",
|
|
"無題のリミックスのリミックスのリミックスのリミックスのリミックス"
|
|
]
|
|
|
|
joined_names = low_quality.map { |name| "'#{name}'" }.join(',')
|
|
|
|
"name NOT IN (#{joined_names})" unless request.params[:name_quality].blank? || request.params[:name_quality] == "false"
|
|
end
|
|
|
|
def remixed_name(name)
|
|
blanked_name = {
|
|
en: name.blank? ? 'Untitled team' : name,
|
|
ja: name.blank? ? '無名の編成' : name
|
|
}
|
|
|
|
if current_user
|
|
case current_user.language
|
|
when 'en'
|
|
"Remix of #{blanked_name[:en]}"
|
|
when 'ja'
|
|
"#{blanked_name[:ja]}のリミックス"
|
|
end
|
|
else
|
|
"Remix of #{blanked_name[:en]}"
|
|
end
|
|
end
|
|
|
|
def set_from_slug
|
|
@party = Party.where('shortcode = ?', params[:id]).first
|
|
if @party
|
|
@party.favorited = current_user && @party ? @party.is_favorited(current_user) : false
|
|
else
|
|
render_not_found_response('party')
|
|
end
|
|
end
|
|
|
|
def set
|
|
@party = Party.where('id = ?', params[:id]).first
|
|
end
|
|
|
|
def party_params
|
|
return unless params[:party].present?
|
|
|
|
params.require(:party).permit(
|
|
:user_id,
|
|
:local_id,
|
|
:edit_key,
|
|
:extra,
|
|
:name,
|
|
:description,
|
|
:raid_id,
|
|
:job_id,
|
|
:accessory_id,
|
|
:skill0_id,
|
|
:skill1_id,
|
|
:skill2_id,
|
|
:skill3_id,
|
|
:full_auto,
|
|
:auto_guard,
|
|
:auto_summon,
|
|
:charge_attack,
|
|
:clear_time,
|
|
:button_count,
|
|
:turn_count,
|
|
:chain_count,
|
|
:guidebook1_id,
|
|
:guidebook2_id,
|
|
:guidebook3_id
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|