我在下面定义了一个自定义查找程序:
class ContainerGateIn << ActiveRecord::Base
...
def self.search(text)
result = if text
text.split(' ').inject(self) do |result, criteria|
case criteria
when /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/
result.search_by_date(criteria.to_date)
else
result.search_by_text(criteria)
end
end
else
self
end
end
...
end
其中search_by_date和search_by_text被命名为范围,而eager是一个预定义的命名范围,定义为:
named_scope :eager, :include => [{:container_inventory => {:container => [:size_type, :grade]}}, :company, :truck, :hauler]
通过HMT设置关联(has_many:through):
class ContainerDepot << ActiveRecord::Base
has_many :container_inventories
has_many :container_gate_ins, :through => :container_inventories do
end
问题是如果通过ContainerDepot中的关联嵌套调用finder,它会失败,并且ActiveRecord :: Statement :: Invalid,表示该表已被多次指定。
ContainerDepot.first.container_gate_ins.eager.search(text)
=> ActiveRecord::StatementInvalid: PGError: ERROR: table name "container_inventories" specified more than once
我可以通过将整个自定义查找器复制为关联扩展来纠正它:
class ContainerDepot << ActiveRecord::Base
...
has_many :container_gate_ins, :through => :container_inventories do
def search(text)
... custom finder code from ContainerGateIn ...
end
end
...
end
虽然它不是很干,并且引入了一个非常不必要且可能存在问题的冗余,因为必须不时更改自定义查找器以适应其他搜索逻辑。
关于如何做得更好的任何想法?
答案 0 :(得分:0)
您可以将named_scope与lambda一起使用,允许您将参数传递给作用域方法:
named_scope :eager, lambda {|text| {:conditions=>{:name=>text}, :include => [{:container_inventory => {:container => [:size_type, :grade]}}, :company, :truck, :hauler]}}
这应该允许您只包含一个命名范围并过滤。