Class: LiveFixtures::Import
- Inherits:
-
Object
- Object
- LiveFixtures::Import
- Defined in:
- lib/live_fixtures/import.rb,
lib/live_fixtures/import/fixtures.rb,
lib/live_fixtures/import/insertion_order_computer.rb
Overview
An object that facilitates the import of fixtures into a database.
Defined Under Namespace
Classes: Fixtures, InsertionOrderComputer, ProgressBarIterator, SimpleIterator
Constant Summary collapse
- NO_LABEL =
nil
Instance Attribute Summary collapse
-
#alternate_imports ⇒ Hash<String => Proc>
readonly
Map of table_name to import routine.
-
#insert_order ⇒ Object
readonly
Returns the insert order that was specified in the constructor or the inferred one if none was specified.
-
#label_to_id ⇒ Object
readonly
Accessor for string label for a given fixture mapping to it’s db id.
Instance Method Summary collapse
-
#import_all ⇒ Object
Within a transaction, import all the fixtures into the database.
-
#initialize(root_path, insert_order = nil, class_names = {}, **opts) ⇒ LiveFixtures::Import
constructor
Instantiate a new Import with the directory containing your fixtures, and the order in which to import them.
-
#override(table_name, callable) ⇒ Object
Override import of table using a callable object.
Constructor Details
#initialize(root_path, insert_order = nil, class_names = {}, **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.
33 34 35 36 37 38 39 40 41 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 |
# File 'lib/live_fixtures/import.rb', line 33 def initialize(root_path, insert_order = nil, class_names = {}, **opts) = { show_progress: true, skip_missing_tables: false, skip_missing_refs: false, use_insert_order_as_table_names: false, } = .merge(opts) @root_path = root_path if insert_order && [:use_insert_order_as_table_names] @table_names = insert_order else @table_names = Dir.glob(File.join(@root_path, '{*,**}/*.yml')).map do |filepath| File.basename filepath, ".yml" end end @class_names = class_names @table_names.each { |n| @class_names[n.tr('/', '_').to_sym] ||= n.classify if n.include?('/') } @insert_order = insert_order @insert_order ||= InsertionOrderComputer.compute(@table_names, @class_names, compute_polymorphic_associations) @table_names = @insert_order.select {|table_name| @table_names.include? table_name} if @table_names.size < @insert_order.size && ![: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 = {} @alternate_imports = {} end |
Instance Attribute Details
#alternate_imports ⇒ Hash<String => Proc> (readonly)
Map of table_name to import routine
13 14 15 |
# File 'lib/live_fixtures/import.rb', line 13 def alternate_imports @alternate_imports end |
#insert_order ⇒ Object (readonly)
Returns the insert order that was specified in the constructor or the inferred one if none was specified.
9 10 11 |
# File 'lib/live_fixtures/import.rb', line 9 def insert_order @insert_order end |
#label_to_id ⇒ Object (readonly)
Accessor for string label for a given fixture mapping to it’s db id
16 17 18 |
# File 'lib/live_fixtures/import.rb', line 16 def label_to_id @label_to_id end |
Instance Method Details
#import_all ⇒ 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`.
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/live_fixtures/import.rb', line 77 def import_all connection = ActiveRecord::Base.connection show_progress = [:show_progress] # TODO: should be additive with alternate_imports so we can delete the fixture file files_to_read = @table_names return if files_to_read.empty? connection.transaction(requires_new: true) do files_to_read.each do |path| table_name = path.tr '/', '_' if alternate = @alternate_imports[table_name] time = Benchmark.ms do alternate.call(@label_to_id) end puts "Imported %s in %.0fms" % [table_name, time] if show_progress else 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: [:skip_missing_refs]) conn = ff.model_connection || connection iterator = show_progress ? ProgressBarIterator : SimpleIterator iterator.new(ff).each do |tname, label, row| conn.insert_fixture(row, tname) @label_to_id[label] = conn.send(:last_inserted_id, tname) unless label == NO_LABEL end end end end end |
#override(table_name, callable) ⇒ Object
Override import of table using a callable object
119 120 121 122 |
# File 'lib/live_fixtures/import.rb', line 119 def override(table_name, callable) @alternate_imports[table_name] = callable self end |