Change fixtures API and internal code

I am fixing bugs in fixtures.rb, and would like to propose some API
and internal code changes.

1. Make TestFixtures::fixture_table_names hold a hash?

I would like to make the (undocumented?) class attribute
`TestFixtures::fixture_table_names` to hold a Hash of the form

{ "fixture_name" => :table_name, ... }

similarly to `TestFixtures::fixture_class_names` holding a Hash of the
form

{ "fixture_name" => FixtureModelClass, ... }

Currently `TestFixtures::fixture_table_names` holds an Array, which
does not seem very useful, seems inconsistent with
`fixture_class_names`, and is not apparently used anywhere except for
tests.

2. Models vs classes in variable and method names?

I would also propose to rename `fixture_class_names` to
`fixture_model_names` and `set_fixture_classes` to
`set_fixture_models`: this seems more flexible and descriptive to me.

3. Make set_fixture_classes only accept classes?

Currently both are acceptable:

set_fixture_classes "admin/users" => Administrator,
                    :customers    => "Client"

Is there a situation where one cannot pass the class and can only pass
its name?
If `set_fixture_classes` would only accept classes, the code would be
somewhat simpler, i guess.

4. Standardize the fixture name in the form "admin/users" (rather
than :admin_users) and use it as fixtures's identifier, instead of
table name?

It seems that originally the idea was to use the table name as the
unique identifier of the collections of fixtures intended to fill that
table, but now this seems all messed up, variable names like
`fixture_name`, `table_name`, `fixture_path` are used with different
contents and sometimes interchangeably.
Since the method `fixtures` accept their names in the form `"admin/
users"`, i propose to use this short path to the fixture file as the
name and identifier of the collection of fixtures, and use
`fixture_name` only in this sense.
The table name should be defined in the associated model, or by a new
method `set_fixture_tables` analogous to `set_fixture_classes`, and
only when there is no associated model, or the associated model does
not respond to `table_name` method and the table name was not set with
`set_fixture_tables`, should the table name be inferred from fixture
name by substitution `tr('/','_')`.

5. Rename Fixture to FixtureInstance and Fixtures to
FixtureCollection?

It took me some time to understand that `ActiveRecord::Fixtures` is
used for the contents of fixture files, and `ActiveRecord::Fixture` is
for a single record.
How about renaming `Fixture` to `FixtureInstance`?
I do not think this class is even documented, so shouldn't be a
problem.
Also, maybe 'FixtureCollection' would be better than `Fixtures`?

It is also not clear to me why `ActiveRecord::Fixture` is needed:
isn't it enough that each entry of `ActiveRecord::Fixtures` can be
converted to a hash or to an instance of the associated model?

What do you think?

Alexey.

I forgot one more:

6. Rename ActiveRecord::TestFixtures.fixture_path to
ActiveRecord::TestFixtures.fixtures_directory?

`ActiveRecord::TestFixtures.fixture_path` holds the path to the
fixture files directory, and is sometimes stored in
`fixtures_directory` variable elsewhere (in
`ActiveRecord::Fixtures.create_fixtures`), and `fixture_path` is often
used for the path to a single fixture file.

There seem also to be confusion with the use `fixture_path` and
`fixtures_directory` local variables.

A.

Just to illustrate what i am talking about, here is a line from
fixtures.rb (around #807):

raise StandardError, "No fixture with name '#{fixture}' found for
table '#{fixture_name}'"

Alexey.

I've created a pull request with proposed changes, please let me know
what you think:

https://github.com/rails/rails/pull/4367

Alexey.