3

I am attempting to use inheritance from a class which has a named scope:

Class A < ActiveRecord::Base
    scope :useful_scope, lambda { |value1, value2|
        where(:value1 => value1, :value2 => value2)
    end
end

Class B < A
    set_table_name "b"
end

The problem I'm encountering is that the table name in the sql queries still reference Class A's Table:

A.useful_scope("alpha", "beta").to_sql
 => "SELECT \"a\".* FROM \"a\" WHERE \"a\".\"value1\" = 'alpha' AND \"a\".\"value2\" = 'beta'"
B.useful_scope("alpha", "beta").to_sql
 => "SELECT \"b\".* FROM \"b\" WHERE \"a\".\"value1\" = 'alpha' AND \"a\".\"value2\" = 'beta'"

Note that the table names in the WHERE statement still refer to A. I am modifying an existing gem with various dependencies on the Class A scope throughout, so I need to maintain it's current syntax. I want to maintain the table name specifiers in the WHERE clause SQL to ensure that the scope will behave well when nested with other named scope definitions.

I have tried the following:

  • Using a lambda parameter for the table name. This broke the syntax for other references to the scope which only provided the current 2 properties.
  • Using an abstract class to define the scope. The same binding of the table name occurred, but using the class name of the Abstract Class.
  • Using a scope defined in a module and including the module. The same binding of the table name occurred.

Is there a way that I can force the scope to be evaluated on each inherited class, so that it isn't explicitly mapped to the parent classes table?

Ben Zittlau
  • 2,345
  • 1
  • 21
  • 30

2 Answers2

3

I ended up using an anonymous scope to resolve this issue. The code looks like this:

def self.useful_scope(value1, value2)
  scoped(:conditions => { :value1 => value1, :value2 => value2 })
end

This now evaluates properly in both the parent and inherited classes, and retains the desired behavior of a scope.

Ben Zittlau
  • 2,345
  • 1
  • 21
  • 30
2

Try this:

class A < ActiveRecord::Base
  def self.useful_scope(value1, value2)
    where(:value1 => value1, :value2 => value2)
  end
end

The difference here is that no Proc/lambda is defined so the :valueN keys don't get associated to the A table.

20man
  • 1,419
  • 13
  • 11
  • Thanks for the answer, but my concern with this implementation is I don't believe it will have the chaining properties that make scopes so useful. I ended up using a solution using an anonymous scope. – Ben Zittlau Mar 29 '11 at 17:34
  • 3
    Your concern is unfounded... the class method returns an ActiveRecord::Relation, same as any scope. – 20man Mar 30 '11 at 04:41