views:

69

answers:

1

I am trying to have a pack of very generic named scopes for ActiveRecord models like this one:

module Scopes
  def self.included(base)
    base.class_eval do
      named_scope :not_older_than, lambda {|interval|
        {:conditions => ["#{table_name}.created_at >= ?", interval.ago]
      }
    end
  end
end
ActiveRecord::Base.send(:include, Scopes)

class User < ActiveRecord::Base
end

If the named scope should be general, we need to specify *table_name* to prevent naming problems if their is joins that came from other chained named scope.

The problem is that we can't get table_name because it is called on ActiveRecord::Base rather then on User.

User.not_older_than(1.week)

NoMethodError: undefined method `abstract_class?' for Object:Class
from /var/lib/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:2207:in `class_of_active_record_descendant'
from /var/lib/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:1462:in `base_class'
from /var/lib/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:1138:in `reset_table_name'
from /var/lib/gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:1134:in `table_name'
from /home/bogdan/makabu/railsware/startwire/repository/lib/core_ext/active_record/base.rb:15:in `included'
from /var/lib/gems/1.8/gems/activerecord-2.3.5/lib/active_record/named_scope.rb:92:in `call'
from /var/lib/gems/1.8/gems/activerecord-2.3.5/lib/active_record/named_scope.rb:92:in `named_scope'
from /var/lib/gems/1.8/gems/activerecord-2.3.5/lib/active_record/named_scope.rb:97:in `call'
from /var/lib/gems/1.8/gems/activerecord-2.3.5/lib/active_record/named_scope.rb:97:in `not_older_than'

How can I get actual table_name at Scopes module?

+3  A: 

Try using the #scoped method inside a class method of ActiveRecord::Base. This should work:

module Scopes
  def self.included(base)
    base.class_eval do
      def self.not_older_than(interval)
        scoped(:conditions => ["#{table_name}.created_at > ?", interval.ago])
      end
    end
  end
end

ActiveRecord::Base.send(:include, Scopes)
Sidane
any idea on how to do this for a default_scope? I am running into the same problem, but I'm calling default_scope rather than named_scope
gmoniey