require 'active_record' namespace :db do desc %q{Loads a specified fixture file: use rake db:load_file[/absolute/path/to/sample/filename.rb]} task :load_file, [:file, :dir] => :environment do |_t, args| file = Pathname.new(args.file) puts "loading ruby #{file}" load file end desc 'Loads fixtures from the the dir you specify using rake db:load_dir[loadfrom]' task :load_dir, [:dir] => :environment do |_t, args| dir = args.dir dir = File.join(Rails.root, 'db', dir) if Pathname.new(dir).relative? ruby_files = {} Dir.glob(File.join(dir, '**/*.{rb}')).each do |fixture_file| ext = File.extname fixture_file ruby_files[File.basename(fixture_file, '.*')] = fixture_file end ruby_files.sort.each do |fixture, ruby_file| # If file exists within application it takes precedence. if File.exist?(File.join(Rails.root, 'db/default/spree', "#{fixture}.rb")) ruby_file = File.expand_path(File.join(Rails.root, 'db/default/spree', "#{fixture}.rb")) end # an invoke will only execute the task once Rake::Task['db:load_file'].execute(Rake::TaskArguments.new([:file], [ruby_file])) end end desc 'Migrate schema to version 0 and back up again. WARNING: Destroys all data in tables!!' task remigrate: :environment do require 'highline/import' if ENV['SKIP_NAG'] || ENV['OVERWRITE'].to_s.casecmp('true').zero? || agree("This task will destroy any data in the database. Are you sure you want to \ncontinue? [y/n] ") # Drop all tables ActiveRecord::Base.connection.tables.each { |t| ActiveRecord::Base.connection.drop_table t } # Migrate upward Rake::Task['db:migrate'].invoke # Dump the schema Rake::Task['db:schema:dump'].invoke else say 'Task cancelled.' exit end end desc 'Bootstrap is: migrating, loading defaults, sample data and seeding (for all extensions) and load_products tasks' task :bootstrap do require 'highline/import' # remigrate unless production mode (as safety check) if %w[demo development test].include? Rails.env if ENV['AUTO_ACCEPT'] || agree("This task will destroy any data in the database. Are you sure you want to \ncontinue? [y/n] ") ENV['SKIP_NAG'] = 'yes' Rake::Task['db:create'].invoke Rake::Task['db:remigrate'].invoke else say 'Task cancelled, exiting.' exit end else say 'NOTE: Bootstrap in production mode will not drop database before migration' Rake::Task['db:migrate'].invoke end ActiveRecord::Base.send(:subclasses).each(&:reset_column_information) load_defaults = Spree::Country.count == 0 load_defaults ||= agree('Countries present, load sample data anyways? [y/n]: ') Rake::Task['db:seed'].invoke if load_defaults if Rails.env.production? && Spree::Product.count > 0 load_sample = agree('WARNING: In Production and products exist in database, load sample data anyways? [y/n]:') else load_sample = true if ENV['AUTO_ACCEPT'] load_sample ||= agree('Load Sample Data? [y/n]: ') end if load_sample # Reload models' attributes in case they were loaded in old migrations with wrong attributes ActiveRecord::Base.descendants.each(&:reset_column_information) Rake::Task['spree_sample:load'].invoke end puts "Bootstrap Complete.\n\n" end desc 'Fix orphan line items after upgrading to Spree 3.1: only needed if you have line items attached to deleted records with Slug (product) and SKU (variant) duplicates of non-deleted records.' task fix_orphan_line_items: :environment do |_t, _args| def get_input STDOUT.flush input = STDIN.gets.chomp case input.upcase when 'Y' return true when 'N' puts 'aborting .....' return false else return true end end puts 'WARNING: This task will re-associate any line_items associated with deleted variants to non-deleted variants with matching SKUs. Because other attributes and product associations may switch during the re-association, this may have unintended side-effects. If this task finishes successfully, line items for old order should no longer be orphaned from their variants. You should run this task after you have already run the db migratoin AddDiscontinuedToProductsAndVariants. If the db migration did not warn you that it was leaving deleted records in place because of duplicate SKUs, then you do not need to run this rake task.' puts 'Are you sure you want to continue? (Y/n):' if get_input puts 'looping through all your deleted variants ...' # first verify that I can really fix all of your line items no_live_variants_found = [] variants_to_fix = [] Spree::Variant.deleted.each do |variant| # check if this variant has any line items at all next if variant.line_items.none? variants_to_fix << variant dup_variant = Spree::Variant.find_by(sku: variant.sku) if dup_variant # this variant is OK else no_live_variants_found << variant end end if variants_to_fix.none? abort('ABORT: You have no deleted variants that are associated to line items. You do not need to run this raks task.') end if no_live_variants_found.any? puts "ABORT: Unfortunately, I found some deleted variants in your database that do not have matching non-deleted variants to replace them with. This script can only be used to cleanup deleted variants that have SKUs that match non-deleted variants. To continue, you must either (1) un-delete these variants (hint: mark them 'discontinued' instead) or (2) create new variants with a matching SKU for each variant in the list below." no_live_variants_found.each do |deleted_variant| puts "variant id #{deleted_variant.id} (sku is '#{deleted_variant.sku}') ... no match found" end abort end puts 'Ready to fix...' variants_to_fix.each do |variant| dup_variant = Spree::Variant.find_by(sku: variant.sku) puts "Changing all line items for #{variant.sku} variant id #{variant.id} (deleted) to variant id #{dup_variant.id} (not deleted) ..." Spree::LineItem.unscoped.where(variant_id: variant.id).update_all(variant_id: dup_variant.id) end puts 'DONE ! Your database should no longer have line items that are associated with deleted variants.' end end desc 'Migrates taxon icons to spree assets after upgrading to Spree 3.4: only needed if you used taxons icons.' task migrate_taxon_icons: :environment do |_t, _args| Spree::Taxon.where.not(icon_file_name: nil).find_each do |taxon| taxon.create_icon(attachment_file_name: taxon.icon_file_name, attachment_content_type: taxon.icon_content_type, attachment_file_size: taxon.icon_file_size, attachment_updated_at: taxon.icon_updated_at) end end desc 'Migrates taxon icons to taxon images after upgrading to Spree 3.7: only needed if you used taxons icons.' task migrate_taxon_icons_to_images: :environment do |_t, _args| Spree::Asset.where(type: 'Spree::TaxonIcon').update_all(type: 'Spree::TaxonImage') end desc 'Ensure all Order associated with Store after upgrading to Spree 3.7' task associate_orders_with_store: :environment do |_t, _args| Spree::Order.where(store_id: nil).update_all(store_id: Spree::Store.default.id) end desc 'Ensure all Order has currency present after upgrading to Spree 3.7' task ensure_order_currency_presence: :environment do |_t, _args| Spree::Order.where(currency: nil).find_in_batches do |orders| orders.each do |order| order.update!(currency: order.store.default_currency) end end end end namespace :core do desc 'Set "active" status on draft products where make_active_at is in the past' task activate_products: :environment do |_t, _args| Spree::Product.where('make_active_at <= ?', Time.current).where(status: 'draft').update_all(status: 'active', updated_at: Time.current) end desc 'Set "archived" status on active products where discontinue_on is in the past' task archive_products: :environment do |_t, _args| Spree::Product.where('discontinue_on <= ?', Time.current).where.not(status: 'archived').update_all(status: 'archived', updated_at: Time.current) end end