Browse Source

BikeCsvImporter: add import of brands as a separate step

master
Ilya Konanykhin 8 years ago
parent
commit
0f1dab1ad1
  1. 31
      app/models/bike_csv_importer.rb
  2. 10
      app/models/bike_csv_importer/bike_attrs.rb
  3. 7
      app/models/bike_csv_importer/cache.rb
  4. 11
      lib/tasks/import.rake

31
app/models/bike_csv_importer.rb

@ -26,8 +26,9 @@ class BikeCsvImporter
puts "Performing a #{dry_run ? 'DRY RUN' : 'LIVE RUN'} of import" puts "Performing a #{dry_run ? 'DRY RUN' : 'LIVE RUN'} of import"
fetch do |bike_hash| fetch do |bike_hash|
bike = new_bike bike_hash bike = new_bike bike_hash
check_method = dry_run ? :valid? : :save check_method = dry_run ? :valid? : :save
if bike.try check_method if bike.try check_method
puts "Imported #{bike.shop_id}: #{bike}".green puts "Imported #{bike.shop_id}: #{bike}".green
@ -76,6 +77,34 @@ class BikeCsvImporter
end end
end end
# Imports new brands from CSV file (field 'make'). Will print out progress to stdout
#
# @param [Boolean] dry_run If true, does not save data, only shows the progress of validation
def brands(dry_run)
created_count, skipped_count = 0, 0
puts "Performing a #{dry_run ? 'DRY RUN' : 'LIVE RUN'} of brands import"
fetch do |bike_hash|
make = clean_value bike_hash['make']
brand = bike_attr_bike_brand make, true
check_method = dry_run ? :valid? : :save
if brand.try :persisted?
puts "Skipped already existing brand #{brand.brand}"
skipped_count +=1
elsif brand.try check_method
puts "Created brand #{brand.brand}".green
created_count += 1
else
puts "Skipped #{brand.try(:brand) || make}: #{brand.try(:errors).try(:full_messages).try(:join, '; ') || 'object not created'}".red
skipped_count += 1
end
end
puts "#{created_count} brand created, #{skipped_count} brand skipped, total of #{created_count + skipped_count} rows in the CSV"
end
private private

10
app/models/bike_csv_importer/bike_attrs.rb

@ -20,7 +20,7 @@ class BikeCsvImporter
def bike_attrs(bike_hash) def bike_attrs(bike_hash)
bike_attr_fields.each_with_object({}) do |(model_field, csv_field), memo| bike_attr_fields.each_with_object({}) do |(model_field, csv_field), memo|
memo[model_field] = send :"bike_attr_#{ model_field }", clean_value(bike_hash[csv_field]) memo[model_field] = send :"bike_attr_#{model_field}", clean_value(bike_hash[csv_field])
end end
end end
@ -52,9 +52,13 @@ class BikeCsvImporter
value.try(:gsub, /[$]/, '').try :to_i value.try(:gsub, /[$]/, '').try :to_i
end end
def bike_attr_bike_brand(value, new_if_empty = false)
value = 'Unknown' if !value || value =~ /\Aunknown/i
cached_bike_brand value, new_if_empty
end
def bike_attr_bike_brand_id(value) def bike_attr_bike_brand_id(value)
return unless value bike_attr_bike_brand(value, false).try :id
cached_bike_brand(value).try :id
end end
def bike_attr_bike_model_id(value) def bike_attr_bike_model_id(value)

7
app/models/bike_csv_importer/cache.rb

@ -6,12 +6,15 @@ class BikeCsvImporter
@bike_purpose_cache[purpose] ||= BikePurpose.find_by_purpose purpose @bike_purpose_cache[purpose] ||= BikePurpose.find_by_purpose purpose
end end
def cached_bike_brand(brand) def cached_bike_brand(brand, new_if_empty = false)
@bike_brand_cache ||= {} @bike_brand_cache ||= {}
if @bike_brand_cache.has_key? brand if @bike_brand_cache.has_key? brand
@bike_brand_cache[brand] @bike_brand_cache[brand]
else else
@bike_brand_cache[brand] = BikeBrand.where('lower(brand) = ?', brand.downcase).first bike_brand = BikeBrand.where('lower(brand) = ?', brand.downcase).first
bike_brand ||= BikeBrand.new(brand: brand) if new_if_empty
@bike_brand_cache[brand] = bike_brand
end end
end end

11
lib/tasks/import.rake

@ -21,5 +21,16 @@ namespace :import do
next puts "File #{file} does not exist or is unreachable" unless File.readable? file next puts "File #{file} does not exist or is unreachable" unless File.readable? file
BikeCsvImporter.new(file).analyze field ? [field] : [] BikeCsvImporter.new(file).analyze field ? [field] : []
end end
# Imports new brands from CSV file
#
# rake import:bikes:brands_csv[import.csv,dry] # dry run
# rake import:bikes:brands_csv[import.csv] # live import
task :brands_csv, [:file, :dry_run] => :environment do |t, args|
file, dry_run = args.values_at :file, :dry_run
next puts "Usage: rake #{t.name}[$csv_file_path[,$dry_run=dry]]" unless file
next puts "File #{file} does not exist or is unreachable" unless File.readable? file
BikeCsvImporter.new(file).brands dry_run == 'dry'
end
end end
end end

Loading…
Cancel
Save