Topic: table_name_prefix and fixture problem when running unit tests

I have an application that has already been written, where we need to add a table_name_prefix so that our database tables don't conflict with other tables in the database they are inhabiting.
I set the config.table_name_prefix in the environment.rb, and my migrates work, the tables are getting the appropriate prefix in the database, but I can mostly continue to use the normal names for the models, etc.  I've run into a couple issues though, that I don't know if they are bugs or whether I'm doing something wrong:

1) Unit tests, test fixtures.  I got the following when attempting to run a unit test:

Exception: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/fixtures.rb:500:in `hosts'
C:\eclipse_workspace\tsis_rails/test/unit/host_test.rb:19:in `test_cascade_delete'
C:/ruby/lib/ruby/1.8/test/unit/testcase.rb:78:in `__send__'
C:/ruby/lib/ruby/1.8/test/unit/testcase.rb:78:in `run'
C:/ruby/lib/ruby/1.8/test/unit/testsuite.rb:34:in `run'
C:/ruby/lib/ruby/1.8/test/unit/testsuite.rb:33:in `each'
C:/ruby/lib/ruby/1.8/test/unit/testsuite.rb:33:in `run'
C:/ruby/lib/ruby/1.8/test/unit/testsuite.rb:34:in `run'
C:/ruby/lib/ruby/1.8/test/unit/testsuite.rb:33:in `each'
C:/ruby/lib/ruby/1.8/test/unit/testsuite.rb:33:in `run'
C:/ruby/lib/ruby/1.8/test/unit/ui/testrunnermediator.rb:46:in `run_suite'
C:/EasyEclipse-for-LAMP-1.2.1.3/plugins/org.rubypeople.rdt.testunit_0.8.0.604272100PRD/ruby/RemoteTestRunner.rb:107:in `start_mediator'
C:/EasyEclipse-for-LAMP-1.2.1.3/plugins/org.rubypeople.rdt.testunit_0.8.0.604272100PRD/ruby/RemoteTestRunner.rb:52:in `start'
C:/EasyEclipse-for-LAMP-1.2.1.3/plugins/org.rubypeople.rdt.testunit_0.8.0.604272100PRD/ruby/RemoteTestRunner.rb:272

I put a print statement in near this line, and found that the @loaded_fixtures hash has an entry at [ActiveRecord::Base.table_name_prefix + table_name + ActiveRecord::Base.table_name_suffix], but NOT at [table_name].

I modified my own copy of fixtures.rb so that it would look for the fixtures in the hash using the table_name prefix and suffix.  This seemed to solve that issue.

Here's my modification:
      def self.setup_fixture_accessors(table_names=nil)
        (table_names || fixture_table_names).each do |table_name|
          # table_name = ActiveRecord::Base.table_name_prefix + table_name.to_s.tr('.','_')
          table_name =  table_name.to_s.tr('.','_')
          define_method(table_name) do |fixture, *optionals|
            force_reload = optionals.shift
            @fixture_cache[table_name] ||= Hash.new
            @fixture_cache[table_name][fixture] = nil if force_reload
            if @loaded_fixtures[ActiveRecord::Base.table_name_prefix + table_name + ActiveRecord::Base.table_name_suffix][fixture.to_s]
              @fixture_cache[table_name][fixture] ||= @loaded_fixtures[ActiveRecord::Base.table_name_prefix + table_name + ActiveRecord::Base.table_name_suffix][fixture.to_s].find
            else
              raise StandardError, "No fixture with name '#{fixture}' found for table '#{table_name}'"
            end
          end
        end
      end


I'm running with Rails 1.2.3, ruby 1.8.6, through the ruby test unit eclipse plugin.
I'm using the 1.15.3 version of the active_record gem.

My question is whether this is the proper way and place to fix this, or if there is some official patch or fix out there.  Also, if not, how do I get the official gem to include such a fix?

2) With that fix in place, I am seeing some errors when I attempt to add a new entry to a table, as part of a unit test.  It is complaining about a primary key violation, when attempting to create a new record.  It doesn't look to me like there should be any primary key violation, when I look at the DB.  This is a postgres database.

Here's the error message I'm getting from the unit test:

Exception: RuntimeError: ERROR    C23505    Mduplicate key violates unique constraint "tsis_hosts_users_pkey"    Fnbtinsert.c    L277    R_bt_check_unique: INSERT INTO tsis_hosts_users ("role_id", "host_id", "user_id") VALUES(3, 1, 9)
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract_adapter.rb:128:in `log'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/postgresql_adapter.rb:152:in `execute'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/postgresql_adapter.rb:136:in `insert'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/base.rb:1811:in `create_without_callbacks'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/callbacks.rb:254:in `create_without_timestamps'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/timestamp.rb:39:in `create'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/base.rb:1789:in `create_or_update_without_callbacks'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/callbacks.rb:242:in `create_or_update'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/base.rb:1545:in `save_without_validation'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/validations.rb:752:in `save_without_transactions'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/transactions.rb:129:in `save'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/connection_adapters/abstract/database_statements.rb:59:in `transaction'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/transactions.rb:95:in `transaction'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/transactions.rb:121:in `transaction'
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/transactions.rb:129:in `save'
C:/eclipse_workspace/tsis_rails/config/../app/models/user.rb:97:in `set_host_role'
C:\eclipse_workspace\tsis_rails/test/unit/user_test.rb:88:in `test_add'
C:/ruby/lib/ruby/1.8/test/unit/testcase.rb:78:in `__send__'
C:/ruby/lib/ruby/1.8/test/unit/testcase.rb:78:in `run'
C:/ruby/lib/ruby/1.8/test/unit/testsuite.rb:34:in `run'
C:/ruby/lib/ruby/1.8/test/unit/testsuite.rb:33:in `each'
C:/ruby/lib/ruby/1.8/test/unit/testsuite.rb:33:in `run'
C:/ruby/lib/ruby/1.8/test/unit/testsuite.rb:34:in `run'
C:/ruby/lib/ruby/1.8/test/unit/testsuite.rb:33:in `each'
C:/ruby/lib/ruby/1.8/test/unit/testsuite.rb:33:in `run'
C:/ruby/lib/ruby/1.8/test/unit/ui/testrunnermediator.rb:46:in `run_suite'
C:/EasyEclipse-for-LAMP-1.2.1.3/plugins/org.rubypeople.rdt.testunit_0.8.0.604272100PRD/ruby/RemoteTestRunner.rb:107:in `start_mediator'
C:/EasyEclipse-for-LAMP-1.2.1.3/plugins/org.rubypeople.rdt.testunit_0.8.0.604272100PRD/ruby/RemoteTestRunner.rb:52:in `start'
C:/EasyEclipse-for-LAMP-1.2.1.3/plugins/org.rubypeople.rdt.testunit_0.8.0.604272100PRD/ruby/RemoteTestRunner.rb:272

There is no entry in the DB for role 3, host 1, user 9.  And it is complaining about the primary key, which is the id in the table, so I think it is somehow trying to use a primary key to insert the new row, that has already been used.

Do you know if there are any issues with the postgres database connector running on windows from within the ruby unit test? Do you know how I might work around this for my unit tests, and whether there is a way to get this fixed if it is a bug?

Re: table_name_prefix and fixture problem when running unit tests

I have not used that option in environment for prefixing the tables.
I always use set_table_name in my models when I have a legacy table that hasn

Re: table_name_prefix and fixture problem when running unit tests

I meet the same issue.

I fix it by hacking the Rails core at :
ruby186-25/lib/ruby/gems/1.8/gems/activerecord-1.15.3/lib/active_record/fixtures.rb

search below:

            if @loaded_fixtures[table_name][fixture.to_s]
              @fixture_cache[table_name][fixture] ||= @loaded_fixtures[table_name

replaced with:
            # hack by RainChen
            # temp fix the table_name_prefix issue
            full_table_name = Fixtures.all_loaded_fixtures[table_name].table_name
            if @loaded_fixtures[full_table_name][fixture.to_s]
              @fixture_cache[table_name][fixture] ||= @loaded_fixtures[full_table_name][fixture.to_s].find
              # hack end

Then everything goes well as usual.

I heart that we could open the class without hacking the original source code.But I don't how to.Anyone could show me the way ?