class ActiveRecord::FixtureSet
def self.cache_fixtures(connection, fixtures_map)
def self.cache_fixtures(connection, fixtures_map) cache_for_connection(connection).update(fixtures_map) end
def self.cache_for_connection(connection)
def self.cache_for_connection(connection) @@all_cached_fixtures[connection] end
def self.cached_fixtures(connection, keys_to_fetch = nil)
def self.cached_fixtures(connection, keys_to_fetch = nil) if keys_to_fetch cache_for_connection(connection).values_at(*keys_to_fetch) else cache_for_connection(connection).values end end
def self.create_fixtures(fixtures_directory, fixture_set_names, class_names = {})
def self.create_fixtures(fixtures_directory, fixture_set_names, class_names = {}) fixture_set_names = Array(fixture_set_names).map(&:to_s) class_names = class_names.stringify_keys # FIXME: Apparently JK uses this. connection = block_given? ? yield : ActiveRecord::Base.connection files_to_read = fixture_set_names.reject { |fs_name| fixture_is_cached?(connection, fs_name) } unless files_to_read.empty? connection.disable_referential_integrity do fixtures_map = {} fixture_sets = files_to_read.map do |fs_name| fixtures_map[fs_name] = new( # ActiveRecord::FixtureSet.new connection, fs_name, class_names[fs_name] || default_fixture_model_name(fs_name), ::File.join(fixtures_directory, fs_name)) end all_loaded_fixtures.update(fixtures_map) connection.transaction(:requires_new => true) do fixture_sets.each do |fs| conn = fs.model_class.respond_to?(:connection) ? fs.model_class.connection : connection table_rows = fs.table_rows table_rows.keys.each do |table| conn.delete "DELETE FROM #{conn.quote_table_name(table)}", 'Fixture Delete' end table_rows.each do |fixture_set_name, rows| rows.each do |row| conn.insert_fixture(row, fixture_set_name) end end end # Cap primary key sequences to max(pk). if connection.respond_to?(:reset_pk_sequence!) fixture_sets.each do |fs| connection.reset_pk_sequence!(fs.table_name) end end end cache_fixtures(connection, fixtures_map) end end cached_fixtures(connection, fixture_set_names) end
def self.default_fixture_model_name(fixture_set_name) # :nodoc:
def self.default_fixture_model_name(fixture_set_name) # :nodoc: ActiveRecord::Base.pluralize_table_names ? fixture_set_name.singularize.camelize : fixture_set_name.camelize end
def self.default_fixture_table_name(fixture_set_name) # :nodoc:
def self.default_fixture_table_name(fixture_set_name) # :nodoc: "#{ ActiveRecord::Base.table_name_prefix }"\ "#{ fixture_set_name.tr('/', '_') }"\ "#{ ActiveRecord::Base.table_name_suffix }".to_sym end
def self.find_table_name(fixture_set_name) # :nodoc:
def self.find_table_name(fixture_set_name) # :nodoc: ActiveSupport::Deprecation.warn( "ActiveRecord::Fixtures.find_table_name is deprecated and shall be removed from future releases. Use ActiveRecord::Fixtures.default_fixture_model_name instead.") default_fixture_model_name(fixture_set_name) end
def self.fixture_is_cached?(connection, table_name)
def self.fixture_is_cached?(connection, table_name) cache_for_connection(connection)[table_name] end
def self.identify(label)
Returns a consistent, platform-independent identifier for +label+.
def self.identify(label) Zlib.crc32(label.to_s) % MAX_ID end
def self.instantiate_all_loaded_fixtures(object, load_instances = true)
def self.instantiate_all_loaded_fixtures(object, load_instances = true) all_loaded_fixtures.each_value do |fixture_set| instantiate_fixtures(object, fixture_set, load_instances) end end
def self.instantiate_fixtures(object, fixture_set, load_instances = true)
def self.instantiate_fixtures(object, fixture_set, load_instances = true) if load_instances fixture_set.each do |fixture_name, fixture| begin object.instance_variable_set "@#{fixture_name}", fixture.find rescue FixtureClassNotFound nil end end end end
def self.reset_cache
def self.reset_cache @@all_cached_fixtures.clear end
def [](x)
def [](x) fixtures[x] end
def []=(k,v)
def []=(k,v) fixtures[k] = v end
def column_names
def column_names @column_names ||= @connection.columns(@table_name).collect { |c| c.name } end
def each(&block)
def each(&block) fixtures.each(&block) end
def has_primary_key_column?
def has_primary_key_column? @has_primary_key_column ||= primary_key_name && model_class.columns.any? { |c| c.name == primary_key_name } end
def inheritance_column_name
def inheritance_column_name @inheritance_column_name ||= model_class && model_class.inheritance_column end
def initialize(connection, name, class_name, path)
def initialize(connection, name, class_name, path) @fixtures = {} # Ordered hash @name = name @path = path if class_name.is_a?(Class) # TODO: Should be an AR::Base type class, or any? @model_class = class_name else @model_class = class_name.constantize rescue nil end @connection = ( model_class.respond_to?(:connection) ? model_class.connection : connection ) @table_name = ( model_class.respond_to?(:table_name) ? model_class.table_name : self.class.default_fixture_table_name(name) ) read_fixture_files end
def primary_key_name
def primary_key_name @primary_key_name ||= model_class && model_class.primary_key end
def read_fixture_files
def read_fixture_files yaml_files = Dir["#{@path}/{**,*}/*.yml"].select { |f| ::File.file?(f) } + [yaml_file_path] yaml_files.each do |file| FixtureSet::File.open(file) do |fh| fh.each do |fixture_name, row| fixtures[fixture_name] = ActiveRecord::Fixture.new(row, model_class) end end end end
def size
def size fixtures.size end
def table_rows
Return a hash of rows to be inserted. The key is the table, the value is
def table_rows now = ActiveRecord::Base.default_timezone == :utc ? Time.now.utc : Time.now now = now.to_s(:db) # allow a standard key to be used for doing defaults in YAML fixtures.delete('DEFAULTS') # track any join tables we need to insert later rows = Hash.new { |h,table| h[table] = [] } rows[table_name] = fixtures.map do |label, fixture| row = fixture.to_hash if model_class && model_class < ActiveRecord::Base # fill in timestamp columns if they aren't specified and the model is set to record_timestamps if model_class.record_timestamps timestamp_column_names.each do |c_name| row[c_name] = now unless row.key?(c_name) end end # interpolate the fixture label row.each do |key, value| row[key] = label if value == "$LABEL" end # generate a primary key if necessary if has_primary_key_column? && !row.include?(primary_key_name) row[primary_key_name] = ActiveRecord::FixtureSet.identify(label) end # If STI is used, find the correct subclass for association reflection reflection_class = if row.include?(inheritance_column_name) row[inheritance_column_name].constantize rescue model_class else model_class end reflection_class.reflect_on_all_associations.each do |association| case association.macro when :belongs_to # Do not replace association name with association foreign key if they are named the same fk_name = (association.options[:foreign_key] || "#{association.name}_id").to_s if association.name.to_s != fk_name && value = row.delete(association.name.to_s) if association.options[:polymorphic] && value.sub!(/\s*\(([^\)]*)\)\s*$/, "") # support polymorphic belongs_to as "label (Type)" row[association.foreign_type] = $1 end row[fk_name] = ActiveRecord::FixtureSet.identify(value) end when :has_and_belongs_to_many if (targets = row.delete(association.name.to_s)) targets = targets.is_a?(Array) ? targets : targets.split(/\s*,\s*/) table_name = association.join_table rows[table_name].concat targets.map { |target| { association.foreign_key => row[primary_key_name], association.association_foreign_key => ActiveRecord::FixtureSet.identify(target) } } end end end end row end rows end
def timestamp_column_names
def timestamp_column_names @timestamp_column_names ||= %w(created_at created_on updated_at updated_on) & column_names end
def yaml_file_path
def yaml_file_path "#{@path}.yml" end