fix artifact import: preload queries, handle symbol keys
This commit is contained in:
parent
5666ee300c
commit
371f2a29dd
1 changed files with 47 additions and 20 deletions
|
|
@ -115,7 +115,13 @@ class ArtifactImportService
|
||||||
# @return [Result] Import result with counts and errors
|
# @return [Result] Import result with counts and errors
|
||||||
def import
|
def import
|
||||||
items = extract_items
|
items = extract_items
|
||||||
return Result.new(success?: false, errors: ['No artifact items found in data']) if items.empty?
|
if items.empty?
|
||||||
|
return Result.new(success?: false, created: [], updated: [], skipped: [], errors: ['No artifact items found in data'])
|
||||||
|
end
|
||||||
|
|
||||||
|
# Preload artifacts and existing collection artifacts to avoid N+1 queries
|
||||||
|
preload_artifacts(items)
|
||||||
|
preload_existing_collection_artifacts(items)
|
||||||
|
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
items.each_with_index do |item, index|
|
items.each_with_index do |item, index|
|
||||||
|
|
@ -143,30 +149,45 @@ class ArtifactImportService
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def preload_artifacts(items)
|
||||||
|
artifact_ids = items.map { |item| (item['artifact_id'] || item[:artifact_id]).to_s }.uniq
|
||||||
|
artifacts = Artifact.where(granblue_id: artifact_ids).index_by(&:granblue_id)
|
||||||
|
@artifacts_cache = artifacts
|
||||||
|
end
|
||||||
|
|
||||||
|
def preload_existing_collection_artifacts(items)
|
||||||
|
game_ids = items.map { |item| (item['id'] || item[:id]).to_s }.uniq
|
||||||
|
existing = @user.collection_artifacts.where(game_id: game_ids).index_by(&:game_id)
|
||||||
|
@existing_cache = existing
|
||||||
|
end
|
||||||
|
|
||||||
def import_item(item, _index)
|
def import_item(item, _index)
|
||||||
artifact = find_artifact(item['artifact_id'])
|
# Handle both string and symbol keys from params
|
||||||
|
data = item.is_a?(Hash) ? item.with_indifferent_access : item
|
||||||
|
|
||||||
|
artifact = find_artifact(data['artifact_id'])
|
||||||
unless artifact
|
unless artifact
|
||||||
@errors << { game_id: item['id'], artifact_id: item['artifact_id'], error: 'Artifact not found' }
|
@errors << { game_id: data['id'], artifact_id: data['artifact_id'], error: 'Artifact not found' }
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check for existing collection artifact with same game ID
|
# Check for existing collection artifact with same game ID
|
||||||
existing = @user.collection_artifacts.find_by(game_id: item['id'].to_s)
|
existing = @existing_cache[data['id'].to_s]
|
||||||
|
|
||||||
if existing
|
if existing
|
||||||
if @update_existing
|
if @update_existing
|
||||||
update_existing_artifact(existing, item, artifact)
|
update_existing_artifact(existing, data, artifact)
|
||||||
else
|
else
|
||||||
@skipped << { game_id: item['id'], reason: 'Already exists' }
|
@skipped << { game_id: data['id'], reason: 'Already exists' }
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
create_collection_artifact(item, artifact)
|
create_collection_artifact(data, artifact)
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_artifact(artifact_id)
|
def find_artifact(artifact_id)
|
||||||
Artifact.find_by(granblue_id: artifact_id.to_s)
|
@artifacts_cache[artifact_id.to_s]
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_collection_artifact(item, artifact)
|
def create_collection_artifact(item, artifact)
|
||||||
|
|
@ -200,16 +221,19 @@ class ArtifactImportService
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_collection_artifact_attrs(item, artifact)
|
def build_collection_artifact_attrs(item, artifact)
|
||||||
|
# Handle both string and symbol keys from params
|
||||||
|
data = item.is_a?(Hash) ? item.with_indifferent_access : item
|
||||||
|
|
||||||
{
|
{
|
||||||
artifact: artifact,
|
artifact: artifact,
|
||||||
game_id: item['id'].to_s,
|
game_id: data['id'].to_s,
|
||||||
element: map_element(item['attribute']),
|
element: map_element(data['attribute']),
|
||||||
proficiency: artifact.quirk? ? map_proficiency(item['kind']) : nil,
|
proficiency: artifact.quirk? ? map_proficiency(data['kind']) : nil,
|
||||||
level: item['level'].to_i,
|
level: data['level'].to_i,
|
||||||
skill1: parse_skill(item['skill1_info']),
|
skill1: parse_skill(data['skill1_info']),
|
||||||
skill2: parse_skill(item['skill2_info']),
|
skill2: parse_skill(data['skill2_info']),
|
||||||
skill3: parse_skill(item['skill3_info']),
|
skill3: parse_skill(data['skill3_info']),
|
||||||
skill4: parse_skill(item['skill4_info'])
|
skill4: parse_skill(data['skill4_info'])
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -225,9 +249,12 @@ class ArtifactImportService
|
||||||
def parse_skill(skill_info)
|
def parse_skill(skill_info)
|
||||||
return {} if skill_info.blank?
|
return {} if skill_info.blank?
|
||||||
|
|
||||||
skill_id = skill_info['skill_id']
|
# Handle both string and symbol keys from params
|
||||||
quality = skill_info['skill_quality'] || skill_info['level']
|
info = skill_info.is_a?(Hash) ? skill_info.with_indifferent_access : skill_info
|
||||||
level = skill_info['level'] || 1
|
|
||||||
|
skill_id = info['skill_id']
|
||||||
|
quality = info['skill_quality'] || info['level']
|
||||||
|
level = info['level'] || 1
|
||||||
|
|
||||||
group, modifier = decode_skill_id(skill_id)
|
group, modifier = decode_skill_id(skill_id)
|
||||||
return {} unless group && modifier
|
return {} unless group && modifier
|
||||||
|
|
@ -266,7 +293,7 @@ class ArtifactImportService
|
||||||
return nil unless skill
|
return nil unless skill
|
||||||
|
|
||||||
base_values = skill.base_values
|
base_values = skill.base_values
|
||||||
return nil if base_values.blank?
|
return nil if base_values.nil? || !base_values.is_a?(Array) || base_values.empty?
|
||||||
|
|
||||||
# Quality 1-5 maps to index 0-4
|
# Quality 1-5 maps to index 0-4
|
||||||
index = (quality - 1).clamp(0, base_values.size - 1)
|
index = (quality - 1).clamp(0, base_values.size - 1)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue