3

I have been working on a project for the last couple months, which was originally developed in 4.1.6 and I am now trying to update it to 4.2.0 (I have incrementally tested all version between 4.1.6 and 4.2.0, and all of the 4.1.x version work without error, and it is only when I go to 4.2.0 that I see the issue I describe here).

In this application, there is a lot of shared functionality that is common to ALL models, so I have created an abstract class, and all of my models inherit from that this class.

class TrackableModel < ActiveRecord::Base
  self.abstract_class = true
  ...
end

class User < TrackableModel
  ...
end

The only change in the Gemfile was changing gem 'rails', '4.1.6' to gem 'rails', '4.2.0'

The update process was following the instructions HERE using rake rails:update and followed it up with the upgrade steps found in section 2 of the same document.

I overwrote all of the conflicting files with the defaults for this rake task, but reviewed each afterwards and worked in my modifications.

Before the update, all tests pass, but after updating

130 runs, 0 assertions, 0 failures, 130 errors, 0 skips

with the error

ActiveRecord::StatementInvalid: Mysql2::Error: Incorrect table name '': SHOW FULL FIELDS FROM ``

Error:
xxxTest#test_yyy:
NoMethodError: undefined method `each' for nil:NilClass

The application seems to work without any changes to the user experience. Everything looks good until I try to execute the tests.

I just can't get my tests to run.

Update:

I forgot to mention that I am running

ruby 2.1.5p273 (2014-11-13 revision 48405) [i386-mingw32].

Additionally, I have been working to follow the execution path. It seems to be failing while it is trying to setup the fixtures. It is going through a loop where it is building the schema_cache of tables. It queries the schema_migrations and my first custom table "customers" (during this call it iterates over each of the columns on this table which appears to be successful).

On the next call to

ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter.columns(table_name#String) 

table_name's value is nil

Unfortunately I am still new enough to ruby/rails that I am having difficulties finding where the table_name values (schema_migrations, customers, nil, ...) is actually being set.

Can someone help point in in the direction of where the list of tables is coming from that is building the schema_cache?

Tezyn
  • 1,314
  • 1
  • 10
  • 24

2 Answers2

5

I encountered the same issue and was able to resolve it. In my case, the base class that inherited from ActiveRecord included a belongs_to :foo statement. I moved that out to the sub-classes of the base class and the fixtures loaded.

So, here is an example:

class BaseAwesomeModel < ActiveRecord::Base
    self.abstract_class = true

    # This is what was causing the issue, moved to subclasses
    # belongs_to :something 
end

class AnotherModel < BaseAwesomeModel
    belongs_to :something
end

class YetAnotherModel < BaseAwesomeModel
    belongs_to :something
end

I'm not sure if this is what is causing your fixtures to fail to load, but it was the source of my issue.

Good luck!

curtp
  • 276
  • 2
  • 7
  • Thanks So much for that! When I made this change, my test classes went back to all passing. On a related not, I tried leaving the belongs_to statements in my abstract_class un-commented, and only adding it to the models that needed it. Of the 12 models inheriting this, only 4 needed this change. The other 8 just seem to work. But if I left it out of any of those 4, 100% of my tests went back to failing. Bizarre! – Tezyn Jan 26 '15 at 23:10
  • It is pretty strange. I am not sure if it is a bug or what. – curtp Jan 27 '15 at 13:31
  • I had a similar problem and resolved it by keeping the association declaration in the abstract class and instead of doing `something: :fixture_name` in the fixtures file I replaced it with `something_id: <%= ActiveRecord::FixtureSet.identify(:fixture_name) %>` – Shadwell Jun 16 '15 at 20:53
  • 1
    I encountered this as well with `enum` on the base class. I copied it to the subclasses but I'll want to look into it later to keep my code DRY. – Aaron Jun 06 '16 at 21:43
0

Just a note for anyone else who comes across this issue and DOESN'T have a relationship defined in the base (abstract) class:

Scopes can also cause this issue with abstract classes (in the same way that belongs_to did for a previous answerer), but apparently if you move them to a class method it works:

Change:

scope :scope_name, -> { #code }

To:

def self.scope_name
  #code
end

My problem was actually caused by something entirely different though. I was previously using the foreigner gem and it has definitions that can look like this in the migrations:

change_table :table_name do |t|
  t.remove_foreign_key :column_name
end

If you move these to the new internalized rails syntax for foreign keys it works:

remove_foreign_key :table_name, :column_name
Joe Edgar
  • 872
  • 5
  • 13