sa1*_*125 1 inheritance activerecord named-scope ruby-on-rails
我试图通过提供一个继承的公共基础模型来概括我的一些模型,其中包含一些相互的named_scope声明和一个激活搜索的过滤器方法,以便在控制器端进行更简单的查询.这在我在控制台中运行时似乎有效,但在控制器中失败:
# in the base model
class GenericModel < ActiveRecord::Base
named_scope :by_name, lambda { |name|
( name.blank? ) ? {} : { :conditions => [ "#{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 < GenericModel
set_table_name 'my_models'
end
# works in in console!
>> params = { :name => 'jimmy' }
>> MyModel.filter(params)
=> [ <#MyModel ...>, ... ]
nil
# fails in controller
@model = MyModel.filter(params)
# ActiveRecord::StatementInvalid (Mysql::Error Unknown column 'generic_models.name' in where clause...)
Run Code Online (Sandbox Code Playgroud)
显然,在rails中调用父类'named_scope,但在rails控制台中可以正常工作.任何想法如何修补这个?谢谢.
由于ActiveRecord试图解释你所说的话,这有点像火车残骸.通常,从ActiveRecord :: Base派生的第一个类用于定义基表名称,并且默认情况下定义它们的子类以使用单表继承(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
Run Code Online (Sandbox Code Playgroud)
您应该能够将扩展包含在该模块中.如果你想进一步清理它,请编写一个初始化程序,它定义一个类似于scoped_by_nameActiveRecord :: Base 的方法来触发这种行为:
class ActiveRecord::Base
def scoped_by_name
extend ByNameExtension
end
end
Run Code Online (Sandbox Code Playgroud)
然后,您可以标记所有需要此类的类:
class MyModel < ActiveRecord::Base
scoped_by_name
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1722 次 |
| 最近记录: |