Skip to content

ActiveRecord scope class method requires a database connection #783

lighthouse-import opened this Issue May 16, 2011 · 5 comments

1 participant


Imported from Lighthouse. Original ticket at:
Created by Peer Allan - 2011-01-18 08:52:34 UTC

ActiveRecord 3 based Rubygem
At our company we had to integrate with a legacy database system. To manage it we created a nice little gem to handle it. Basically the gem was just a collection of ActiveRecord models, nicely namespaced, so that we could include it in any application that made have needed access to that db. In code outside of Rails, where we commonly used the gem we would just do this,

  require 'legacy_database'

Using ActiveRecord 3 this no longer works when used outside of Rails.

  require 'legacy_database' # <= raises ActiveRecord::ConnectionNotEstablished

The backtrace showed us that when the gem was being loaded when it hits the first scope call Arel attempts to connect to the database. Its a classic chicken/egg situation. You can't initialize the connection until you load the gem and you can't load the gem without initializing the connection.

In our situation we aren't using the gem in concert with any other ActiveRecord connections so we are able to use ActiveRecord::Base to establish the connection.

  require 'activerecord'
  require 'legacy_database'
  LegacyDatabase::Foo.find(1)  # It work's

This naturally is not an ideal situation.


Imported from Lighthouse.
Comment by Nick - 2011-01-14 10:56:56 UTC

I've just come across this issue in another project where we manually require AR + all the models, then establish the connection some time afterwards.

My workaround is a class method encapsulating an anonymous scope, e.g.

class Foo
self.scoped.joins(:bar).where(:bars => {:disconnected_at => nil})

Since AR/Arel can't validate such anonymous scopes at require-time, it gets around the problem. It does raise the question of exactly how useful that validation is, though. Obviously, they could just defer it until require_connection is called if there's no connection at require time - but maybe it's not useful and should just be quietly dropped in favour of an error at runtime when you try to use a named scope referencing an invisible table?


Imported from Lighthouse.
Comment by Peer Allan - 2011-03-08 14:30:02 UTC

My original post described a workaround for when you are encountering this problem outside a Rails app. Since then I have tried to work around this in a couple more ways in a Rails 3 application and am not having much luck. Our legacy gem is formatted very much like ActiveRecord

module LegacyDatabase
  class Base < ActiveRecord::Base
    establish_connection :legacy_database # <= important line

If we leave the establish_connection in the gem then we get a configuration not found error. (legacy_database database is not configured (ActiveRecord::AdapterNotSpecified))

If we remove that line then the app starts to load the models that are contained in the gem. However, once it hits an association, for example:

module LegacyDatabase
  class Foo < Base
    has_and_belongs_to_many :bars

We get a ActiveRecord::ConnectionNotEstablished error. Here is the important part of the backtrace:

from /user/me/.rvm/gems/ruby-1.8.7-p334/gems/activerecord-3.0.5/lib/active_record/connection_adapters/abstract/connection_specification.rb:97:in `retrieve_connection'
from /user/me/.rvm/gems/ruby-1.8.7-p334/gems/activerecord-3.0.5/lib/active_record/connection_adapters/abstract/connection_specification.rb:89:in `connection'
from /user/me/.rvm/gems/ruby-1.8.7-p334/gems/activerecord-3.0.5/lib/active_record/associations.rb:1804:in `create_has_and_belongs_to_many_reflection'
from /user/me/.rvm/gems/ruby-1.8.7-p334/gems/activerecord-3.0.5/lib/active_record/associations.rb:1411:in `has_and_belongs_to_many'
from /user/me/.rvm/gems/ruby-1.8.7-p334/gems/activerecord-3.0.5/lib/active_record/autosave_association.rb:137:in `has_and_belongs_to_many'

At this point, we have exhausted all avenues that we can think of, to get around this. It is very unfortunate as this completely blocks our Rails 3 upgrade. Thanks.


Imported from Lighthouse.
Comment by Aaron Patterson - 2011-03-08 16:21:55 UTC

@Peer, can you provide the source for "legacy_database". I cannot debug the problem without knowing why requiring that file will produce an ActiveRecord::ConnectionNotEstablished exception.


Imported from Lighthouse.
Comment by Peer Allan - 2011-03-08 17:40:28 UTC

Attached is a simple gem that demonstrates the problem. Attempt to load it into a Rails 3 application and you will see the errors. Detailed instructions are shown below and included in the legacy_database.rb file. There are 3 scenarios listed in terms of importance.

Three things can be tested by including this gem in your app

  1. scope calls will attempt to connect to the database before a
    connection has been established

  2. has_and_belong_to_many associations in the models will attempt to
    connect to the database before a connection has been established

  3. an establish_connection in the Base class as shown below will
    not work regardless of database.yml settings. Although, setting
    a gem up this way is probably not useful anyway ;)


  1. Include this gem in your rails 3 app's Gemfile gem 'legacy_database', :path => '/path/to/legacy_database'
  2. bundle install the gem

Scenario 1
1) comment out the habtm lines in foo.rb and bar.rb
2) ensure the scope line in baz.rb is not commented out
3) attempt to load the console

Scenario 2
1) comment out scope in baz.rb
2) Ensure the habtm lines in bar.rb and foo.rb are not commented out
3) attempt to load the console

Scenario 3
1) uncomment the 'establish_connection' line in this file and attempt
to load a console
2) add a legacdy_database config to your database.yml and load the console

I also tested it with a "has_many" and a "has_many :through" relationships which did not cause the same problem. Therefore the workaround if a habtm is required is that you have to use a "has_many :through". That said, the association issues and establish_connection are only related side effects. Its the problem that primarily affects us (so now we have a workaround, yay!). The scope issues is the big fish in this ticket.


Imported from Lighthouse.
Comment by Jon Leighton - 2011-03-08 18:22:58 UTC

It's caused by this line:

That test and the preceding one ought to be in AssociationReflection#check_validity! I think. I added a TODO comment for this in master, but I haven't got round TODOing it yet ;)

@ventsislaf ventsislaf pushed a commit to notonthehighstreet/delayed_job_active_record that referenced this issue Jan 15, 2015
@guiocavalcanti guiocavalcanti Defining scope as class methods. Workaround to rails/rails#783. Closes d4b26c9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.