提交 116b9edf 编写于 作者: A Aaron Patterson

Merge pull request #4224 from alexeymuranov/my-fix-for-fixture-tables

Fix #2572 and define fixture table name in the associated model
......@@ -388,10 +388,15 @@ class Fixtures
@@all_cached_fixtures = Hash.new { |h,k| h[k] = {} }
def self.find_table_name(table_name) # :nodoc:
def self.default_fixture_model_name(fixture_name) # :nodoc:
ActiveRecord::Base.pluralize_table_names ?
table_name.to_s.singularize.camelize :
table_name.to_s.camelize
fixture_name.singularize.camelize :
fixture_name.camelize
end
def self.default_fixture_table_name(fixture_name) # :nodoc:
"#{ActiveRecord::Base.table_name_prefix}"\
"#{fixture_name.tr('/', '_')}#{ActiveRecord::Base.table_name_suffix}".to_sym
end
def self.reset_cache
......@@ -441,9 +446,6 @@ def self.instantiate_all_loaded_fixtures(object, load_instances = true)
def self.create_fixtures(fixtures_directory, table_names, class_names = {})
table_names = [table_names].flatten.map { |n| n.to_s }
table_names.each { |n|
class_names[n.tr('/', '_').to_sym] = n.classify if n.include?('/')
}
# FIXME: Apparently JK uses this.
connection = block_given? ? yield : ActiveRecord::Base.connection
......@@ -457,12 +459,12 @@ def self.create_fixtures(fixtures_directory, table_names, class_names = {})
fixtures_map = {}
fixture_files = files_to_read.map do |path|
table_name = path.tr '/', '_'
fixture_name = path
fixtures_map[path] = ActiveRecord::Fixtures.new(
fixtures_map[fixture_name] = new( # ActiveRecord::Fixtures.new
connection,
table_name,
class_names[table_name.to_sym] || table_name.classify,
fixture_name,
class_names[fixture_name] || default_fixture_model_name(fixture_name),
::File.join(fixtures_directory, path))
end
......@@ -506,25 +508,27 @@ def self.identify(label)
attr_reader :table_name, :name, :fixtures, :model_class
def initialize(connection, table_name, class_name, fixture_path)
def initialize(connection, fixture_name, class_name, fixture_path)
@connection = connection
@table_name = table_name
@fixture_path = fixture_path
@name = table_name # preserve fixture base name
@name = fixture_name
@class_name = class_name
@fixtures = ActiveSupport::OrderedHash.new
@table_name = "#{ActiveRecord::Base.table_name_prefix}#{@table_name}#{ActiveRecord::Base.table_name_suffix}"
# Should be an AR::Base type class
if class_name.is_a?(Class)
@table_name = class_name.table_name
@connection = class_name.connection
@model_class = class_name
@model_class = class_name
else
@model_class = class_name.constantize rescue nil
@model_class = class_name.constantize rescue nil
end
@connection = model_class.connection if model_class && model_class.respond_to?(:connection)
@table_name = ( model_class.respond_to?(:table_name) ?
model_class.table_name :
self.class.default_fixture_table_name(fixture_name) )
read_fixture_files
end
......@@ -723,14 +727,29 @@ module TestFixtures
self.use_instantiated_fixtures = false
self.pre_loaded_fixtures = false
self.fixture_class_names = Hash.new do |h, table_name|
h[table_name] = ActiveRecord::Fixtures.find_table_name(table_name)
self.fixture_class_names = Hash.new do |h, fixture_name|
h[fixture_name] = ActiveRecord::Fixtures.default_fixture_model_name(fixture_name)
end
end
module ClassMethods
# Sets the model class for a fixture when the class name cannot be inferred from the fixture name.
#
# Examples:
#
# set_fixture_class :some_fixture => SomeModel,
# 'namespaced/fixture' => Another::Model
#
# The keys must be the fixture names, that coincide with the short paths to the fixture files.
#--
# It is also possible to pass the class name instead of the class:
# set_fixture_class 'some_fixture' => 'SomeModel'
# I think this option is redundant, i propose to deprecate it.
# Isn't it easier to always pass the class itself?
# (2011-12-20 alexeymuranov)
#++
def set_fixture_class(class_names = {})
self.fixture_class_names = self.fixture_class_names.merge(class_names)
self.fixture_class_names = self.fixture_class_names.merge(class_names.stringify_keys)
end
def fixtures(*fixture_names)
......@@ -770,9 +789,9 @@ def setup_fixture_accessors(fixture_names = nil)
fixture_names = Array.wrap(fixture_names || fixture_table_names)
methods = Module.new do
fixture_names.each do |fixture_name|
fixture_name = fixture_name.to_s.tr('./', '_')
accessor_name = fixture_name.tr('/', '_').to_sym
define_method(fixture_name) do |*fixtures|
define_method(accessor_name) do |*fixtures|
force_reload = fixtures.pop if fixtures.last == true || fixtures.last == :reload
@fixture_cache[fixture_name] ||= {}
......@@ -785,13 +804,13 @@ def setup_fixture_accessors(fixture_names = nil)
@fixture_cache[fixture_name][fixture] ||= @loaded_fixtures[fixture_name][fixture.to_s].find
end
else
raise StandardError, "No fixture with name '#{fixture}' found for table '#{fixture_name}'"
raise StandardError, "No entry named '#{fixture}' found for fixture collection '#{fixture_name}'"
end
end
instances.size == 1 ? instances.first : instances
end
private fixture_name
private accessor_name
end
end
include methods
......
require 'cases/helper'
require 'models/admin'
require 'models/admin/account'
require 'models/admin/randomly_named_c1'
require 'models/admin/user'
require 'models/binary'
require 'models/book'
......@@ -14,6 +15,7 @@
require 'models/parrot'
require 'models/pirate'
require 'models/post'
require 'models/randomly_named_c1'
require 'models/reply'
require 'models/ship'
require 'models/task'
......@@ -745,3 +747,34 @@ def test_does_not_logs_message_for_successful_dependency_load
ActiveRecord::TestCase.try_to_load_dependency(:works_out_fine)
end
end
class CustomNameForFixtureOrModelTest < ActiveRecord::TestCase
ActiveRecord::Fixtures.reset_cache
set_fixture_class :randomly_named_a9 =>
ClassNameThatDoesNotFollowCONVENTIONS,
:'admin/randomly_named_a9' =>
Admin::ClassNameThatDoesNotFollowCONVENTIONS,
'admin/randomly_named_b0' =>
Admin::ClassNameThatDoesNotFollowCONVENTIONS
fixtures :randomly_named_a9, 'admin/randomly_named_a9',
:'admin/randomly_named_b0'
def test_named_accessor_for_randomly_named_fixture_and_class
assert_kind_of ClassNameThatDoesNotFollowCONVENTIONS,
randomly_named_a9(:first_instance)
end
def test_named_accessor_for_randomly_named_namespaced_fixture_and_class
assert_kind_of Admin::ClassNameThatDoesNotFollowCONVENTIONS,
admin_randomly_named_a9(:first_instance)
assert_kind_of Admin::ClassNameThatDoesNotFollowCONVENTIONS,
admin_randomly_named_b0(:second_instance)
end
def test_table_name_is_defined_in_the_model
assert_equal :randomly_named_table, ActiveRecord::Fixtures::all_loaded_fixtures["admin/randomly_named_a9"].table_name
assert_equal :randomly_named_table, Admin::ClassNameThatDoesNotFollowCONVENTIONS.table_name
end
end
first_instance:
some_attribute: AAA
another_attribute: 000
second_instance:
some_attribute: BBB
another_attribute: 999
first_instance:
some_attribute: AAA
another_attribute: 000
second_instance:
some_attribute: BBB
another_attribute: 999
first_instance:
some_attribute: AAA
another_attribute: 000
second_instance:
some_attribute: BBB
another_attribute: 999
class Admin::ClassNameThatDoesNotFollowCONVENTIONS < ActiveRecord::Base
self.table_name = :randomly_named_table
end
class ClassNameThatDoesNotFollowCONVENTIONS < ActiveRecord::Base
self.table_name = :randomly_named_table
end
......@@ -505,6 +505,11 @@ def create_table(*args, &block)
t.string :type
end
create_table :randomly_named_table, :force => true do |t|
t.string :some_attribute
t.integer :another_attribute
end
create_table :ratings, :force => true do |t|
t.integer :comment_id
t.integer :value
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册