Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

arel methods in scope cause issues with non-existent tables

#4142

While working on a Rails 3 project, I've stumbled across an issue concerning the use of arel methods in scopes instead of the soon to be deprecated hash syntax. The issue arises if a model's table doesn't exist yet but the model is being loaded as part of the environment – which, for example, happens if an observer is defined on said model or if initializers load/extend a model.

# app/models/post.rb
class Post < ActiveRecord::Base
  scope :published, where(:published => true)
end

# app/observers/post_observer.rb
class PostObserver < ActiveRecord::Observer
  observe :post
end

# config/application.rb
config.active_record.observers = [:post_observer]

Now, if the posts table doesn't exist yet, whenever you load the environment you'll get "Could not find table 'posts'". And you can't migrate because that needs to load the environment, too.

A simple way to recreate this without having to define an observer is to just do require 'post' somewhere in the environment or in an initializer.

I don't know much about arel yet but judging from the stack trace, I think that maybe arel tries to load the table structure too early. If so, maybe this could be deferred until evaluation?

I'll try to investigate a bit and see if I can find a solution for this issue.

In the meantime, here's the relevant bit of the stack trace:

/Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/activerecord-3.0.0.beta/lib/active_record/connection_adapters/sqlite_adapter.rb:306:in table_structure': Could not find table 'posts' (ActiveRecord::StatementInvalid)

from /Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/activerecord-3.0.0.beta/lib/active_record/connection_adapters/sqlite_adapter.rb:201:in `columns'
from /Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/arel-0.2.1/lib/arel/engines/sql/engine.rb:17:in `send'
from /Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/arel-0.2.1/lib/arel/engines/sql/engine.rb:17:in `method_missing'
from /Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/arel-0.2.1/lib/arel/engines/sql/relations/table.rb:47:in `columns'
from /Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/arel-0.2.1/lib/arel/engines/sql/relations/table.rb:25:in `attributes'
from /Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/arel-0.2.1/lib/arel/algebra/relations/relation.rb:99:in `find_attribute_matching_name'
from /Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/arel-0.2.1/lib/arel/algebra/relations/relation.rb:89:in `[]'
from /Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/activerecord-3.0.0.beta/lib/active_record/relation/predicate_builder.rb:23:in `build_from_hash'
from /Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/activerecord-3.0.0.beta/lib/active_record/relation/query_methods.rb:185:in `map'
from /Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/activerecord-3.0.0.beta/lib/active_record/relation/predicate_builder.rb:9:in `each'
from /Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/activerecord-3.0.0.beta/lib/active_record/relation/predicate_builder.rb:9:in `map'
from /Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/activerecord-3.0.0.beta/lib/active_record/relation/predicate_builder.rb:9:in `build_from_hash'
from /Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/activerecord-3.0.0.beta/lib/active_record/relation/query_methods.rb:191:in `build_where'
from (eval):3:in `where'
from /Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/activerecord-3.0.0.beta/lib/active_record/base.rb:561:in `__send__'
from /Users/clemens/.rvm/gems/ruby-1.8.7-p249/gems/activerecord-3.0.0.beta/lib/active_record/base.rb:561:in `where'
from /Users/clemens/tmp/scopes/app/models/post.rb:2

Reported by Clemens Kofler · March 10th, 2010 @ 10:02 AM

State: committed
Milestone: 3.0.2
Assigned to: Pratik Pratik
Importance: Medium

Activity

  1. José Valim
  2. Pratik
  3. Emilio Tagua
    Emilio Tagua

    I modified Arel so it doesn't raise an exception if table/columns doesn't exists:

    http://github.com/rails/arel/commit/b706f690b611d647aae15a85caa19d1...

    A patch to make use of this in AR is attached.

    March 10th, 2010 @ 09:24 PM

  4. Repository
    Repository
    • State changed from resolved to committed

    (from [e08c153a08a0af79b36853c0ad8bb6e916ca3e66]) Arel now fallback to using Arel::Attribute if the table/column doesn't exists.

    [#4142 state:committed]

    Signed-off-by: Jeremy Kemper jeremy@bitsweat.net
    http://github.com/rails/rails/commit/e08c153a08a0af79b36853c0ad8bb6...

    March 10th, 2010 @ 09:49 PM

  5. Jeremy Kemper
    Jeremy Kemper
    • Milestone set to 3.0.2
    • Importance changed from to Medium

    October 15th, 2010 @ 11:01 PM