Rails named_scopeinheritance?

我试图通过提供一个inheritance的公共基础模型来概括我的一些模型,其包含一些相互的named_scope声明和一个filter方法,该方法激活该搜索以便在控制器端进行更简单的查询。 这在我在控制台中运行时似乎正在工作,但在控制器中失败时:

# in the base model class GenericModel  [ "#{self.table_name}.name like ?", "%#{name}%" ] } } def filter(params) res = [] res = self.by_name( (params[:name] or '') ) if params[:name] return res end end class MyModel > params = { :name => 'jimmy' } >> MyModel.filter(params) => [ , ... ] nil # fails in controller @model = MyModel.filter(params) # ActiveRecord::StatementInvalid (Mysql::Error Unknown column 'generic_models.name' in where clause...) 

显然,在rails中调用父类’named_scope,但在rails控制台中可以正常工作。 任何想法如何修补这个? 谢谢。

由于ActiveRecord试图解释你所说的话,这有点像火车残骸。 通常,从ActiveRecord :: Base派生的第一个类用于定义基表名称,并且默认情况下定义它们的子类以使用单表inheritance(STI)。 你正在通过使用set_table_name解决这个问题,但通常情况下,虽然它可能会违反Rails中的内容,但事情往往会变得混乱。

你应该能够使用Beerlington建议的mixin更干净地完成这项工作。

 module ByNameExtension def self.extended(base) # This method is called when a class extends with this module base.send(:scope, :by_name, lambda { |name| name.blank? ? nil : where("#{self.table_name}.name LIKE ?", "%#{name}%") }) end def filter(params) params[:name].present? ? self.by_name(params[:name]) : [ ] end end class MyModel < ActiveRecord::Base # Load in class-level methods from module ByNameExtension extend ByNameExtension end 

您应该能够将扩展包含在该模块中。 如果您想进一步清理它,请编写一个初始化程序,为ActiveRecord :: Base定义一个触发此行为的scoped_by_name方法:

 class ActiveRecord::Base def scoped_by_name extend ByNameExtension end end 

然后,您可以标记所有需要此类的类:

 class MyModel < ActiveRecord::Base scoped_by_name end