This project is archived and is in readonly mode.
ActiveRecord scope class method requires a database connection
-
Nick
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
def self.onlineself.scoped.joins(:bar).where(:bars => {:disconnected_at => nil})end end
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?
-
Peer Allan
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 end endIf 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 end endWe 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.
-
Aaron Patterson
- State changed from new to open
- Assigned user set to Aaron Patterson
- Importance changed from to Low
@Peer, can you provide the source for "legacy_database". I cannot debug the problem without knowing why requiring that file will produce an
ActiveRecord::ConnectionNotEstablishedexception. -
Peer Allan
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
-
scope calls will attempt to connect to the database before a
connection has been established -
has_and_belong_to_many associations in the models will attempt to
connect to the database before a connection has been established -
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 ;)
Instructions:
- Include this gem in your rails 3 app's Gemfile
gem 'legacy_database', :path => '/path/to/legacy_database' - 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 consoleScenario 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 consoleScenario 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 consoleI 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.
-
-
Jon Leighton
It's caused by this line:
https://github.com/rails/rails/blob/3-0-stable/activerecord/lib/act...
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 ;)
