Class: LiveFixtures::Import

Inherits:
Object
  • Object
show all
Defined in:
lib/live_fixtures/import.rb,
lib/live_fixtures/import/fixtures.rb

Overview

An object that facilitates the import of fixtures into a database.

Defined Under Namespace

Classes: Fixtures, ProgressBarIterator, SimpleIterator

Constant Summary collapse

NO_LABEL =
nil

Instance Method Summary collapse

Constructor Details

#initialize(root_path, insert_order, **opts) ⇒ LiveFixtures::Import

Instantiate a new Import with the directory containing your fixtures, and the order in which to import them. The order should ensure fixtures containing references to another fixture are imported AFTER the referenced fixture.

Parameters:

  • root_path (String)

    path to the directory containing the yml files to import.

  • insert_order (Array<String>)

    a list of yml files (without .yml extension) in the order they should be imported.

  • opts (Hash)

    export configuration options

Options Hash (**opts):

  • show_progress (Boolean)

    whether or not to show the progress bar

  • skip_missing_tables (Boolean)

    when false, an error will be raised if a yaml file isn’t found for each table in insert_order

  • skip_missing_refs (Boolean)

    when false, an error will be raised if an ID isn’t found for a label.

Raises:

  • (ArgumentError)

    raises an argument error if not every element in the insert_order has a corresponding yml file.

See Also:



18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/live_fixtures/import.rb', line 18

def initialize(root_path, insert_order, **opts)
  defaut_options = { show_progress: true, skip_missing_tables: false, skip_missing_refs: false }
  @options = defaut_options.merge(opts)
  @root_path = root_path
  @table_names = Dir.glob(File.join(@root_path, '{*,**}/*.yml')).map do |filepath|
    File.basename filepath, ".yml"
  end
  @table_names = insert_order.select {|table_name| @table_names.include? table_name}
  if @table_names.size < insert_order.size && !@options[:skip_missing_tables]
    raise ArgumentError, "table(s) mentioned in `insert_order` which has no yml file to import: #{insert_order - @table_names}"
  end
  @label_to_id = {}
end

Instance Method Details

#import_all(class_names = {}) ⇒ Object

Within a transaction, import all the fixtures into the database. The very similar method: ActiveRecord::FixtureSet.create_fixtures has the unfortunate side effect of truncating each table!!

Therefore, we have reproduced the relevant sections here, without DELETEs, with calling LiveFixtures::Import::Fixtures#each_table_row_with_label instead of ‘AR::Fixtures#table_rows`, and using those labels to populate `@label_to_id`.

Parameters:

  • class_names (Hash{Symbol => String}) (defaults to: {})

    a mapping table name => Model class, for any that don’t follow convention.

See Also:



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/live_fixtures/import.rb', line 42

def import_all(class_names = {})
  @table_names.each { |n|
    class_names[n.tr('/', '_').to_sym] ||= n.classify if n.include?('/')
  }

  connection = ActiveRecord::Base.connection

  files_to_read = @table_names

  unless files_to_read.empty?
    connection.transaction(requires_new: true) do
      files_to_read.each do |path|
        table_name = path.tr '/', '_'
        class_name = class_names[table_name.to_sym] || table_name.classify

        ff = Fixtures.new(connection,
                          table_name,
                          class_name,
                          ::File.join(@root_path, path),
                          @label_to_id,
                          skip_missing_refs: @options[:skip_missing_refs])

        conn = ff.model_connection || connection
        iterator = @options[:show_progress] ? ProgressBarIterator : SimpleIterator
        iterator.new(ff).each do |table_name, label, row|
          conn.insert_fixture(row, table_name)
          @label_to_id[label] = conn.last_inserted_id(table_name) unless label == NO_LABEL
        end
      end
    end
  end
end