Search code examples
ruby-on-railsrubyruby-on-rails-4namespacessingle-table-inheritance

Rails 4 - STI with namespace


If I have 3 classes like below:

class Parent < ActiveRecord::Base
end

class Child < Parent
end

class Another::Child < ::Child
end

All those 3 classes are located in different folders.

In rails console, Child.first run this query SELECT parents.* FROM parents WHERE parents.type IN ('Child') ORDER BY parents.id ASC LIMIT 1.

After that, I run Another::Child.first in rails console and this query is generated SELECT parents.* FROM parents WHERE parents.type IN ('Another::Child') ORDER BY parents.id ASC LIMIT 1.

After I run both command in rails console, then I run Child.first again and the query became SELECT parents.* FROM parents WHERE parents.type IN ('Child', 'Another::Child') ORDER BY parents.id ASC LIMIT 1.

What is the cause of that?

How to consistently call the 3rd query whenever I run Another::Child.first considering Another::Child is a child class of Child?


Solution

  • The behavior you described is caused by the lazy loading of your Rails models in development mode (eager loading is disabled by default for developent). Before you run Another::Child.first for the first time Another::Child has not yet been loaded.

    You can enable eager loading in all environments by adding Rails.application.config.eager_load = true to an initializer file.

    The reason to not use eager loading in development is because the app can (re)load much faster. However, I've run into many problems when eager loading is disabled, especially with STI models like you are using. It can become quite a headache to manage, and it can lead to bugs since the development environment behaves differently than the production environment. For those reasons I typically recommend setting eager_load = true.