3

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?

1
  • No. But I checked it now and result is not satisfying: irb(main):001:0> Great::Item.table_name_prefix => "great_" irb(main):002:0> Great::Item.table_name => "items" Commented Apr 29, 2015 at 7:30

2 Answers 2

2

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

Sign up to request clarification or add additional context in comments.

6 Comments

I wrote it didn't work out - same result as set_table_name & reset_table_name. Table name was setted correct but query was builded with wrong table name.
you sure you did add the self ?
ok what if you use set_table_name on top of your class definition?
I didn't expected it will change something but it did the trick.
I tried it earlier but before it i loaded some module and then tried to set_table_name. After replacing lines everything started work.
|
1

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

2 Comments

can't change table names cause it will break backward compatibility with other systems. Moreover on other servers this code works only one of them is exception :)
Then you should go with set_table_name as suggtesed by @apneadiving

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.