SZMER
SZMER

Reputation: 193

Model with namespace - wrong table name (without namespace)

I found a problem in one of legacy applications (outdated rails-3.0.20). This application has lots of components and nested models. Problem existed only on one of production servers (same environments like other productions and mine dev).

There was model with name space which looks like

module Great
  class Item
  end
end

Table name was named great_items.

When i debug/open it on server with fault i've found that calculated table name was items istead of great_items.

$ Great::Item.all
#=> ActiveRecord::StatementInvalid: No attribute named `name` exists for table `items`

So i thought mby there is simmilar class with same namespace, I've checked it and it wasn't. My 2nd thought was to set table name explicit i tried

self.table_name = 'great_items'
# &
set_table_name 'great_items'

After this changes i run rails c and table name was setted fine:

$ Great::Item.table_name
#=> 'great_items'

But when i tried to obtain some items there was a freak error, which i could not understand till now!

$ Great::Item.all
#=> ActiveRecord::StatementInvalid: Mysql2::Error: Table 'db.items' doesn't exist: SELECT `great_items`.* FROM `items` WHERE `great_items`.`some_default_scope` = 0

As you can see in above example table has correct name for select values and in where statement, but in from value is incorrect.

I was curious so I've checked ActiveRecord::Base mysql adapter and there was some kind of catching table name so i tried to reset_table_name. Reset helped to setup expected name('great_items') but above errors didn't missed.

Problem dissapeared when i turn of class catching in production enviroment - but it wasn't solution.

Finally I kinda 'solved' this using reset_column_information after set_table_name, but i think it isn't good solution either.

My question is do you know what really could cause this issue and how to solve it without reloading class cache?

Upvotes: 3

Views: 1265

Answers (2)

apneadiving
apneadiving

Reputation: 115541

Assumed table names dont take into account the modules, as you noticed.

But as you already know, you can set it yourself, using:

self.table_name = 'great_items'

According to this doc, because you use 3.0.x, you have to use:

set_table_name "great_items"

This must be put on top of your class definition

Upvotes: 2

Xeeshan
Xeeshan

Reputation: 156

Try this

class RenameOldTableToNewTable< ActiveRecord::Migration
  def self.up
    rename_table :old_table_name, :new_table_name
  end 
  def self.down
    rename_table :new_table_name, :old_table_name
  end
end

Upvotes: 1

Related Questions