【问题标题】:Custom ActiveRecord finder invoking named scopes?调用命名范围的自定义 ActiveRecord 查找器?
【发布时间】:2010-02-03 07:14:46
【问题描述】:

我在下面定义了一个自定义查找器:

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 的关联嵌套调用的,它会失败并返回 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

虽然它不是很干燥,并且引入了非常不必要且可能有问题的冗余,因为必须不时更改自定义查找器以适应额外的搜索逻辑。

有什么想法可以做得更好吗?

【问题讨论】:

    标签: ruby-on-rails ruby activerecord named-scope


    【解决方案1】:

    您可以将 named_scope 与 lambda 一起使用,允许您将参数传递给作用域方法:

    named_scope :eager, lambda {|text| {:conditions=>{:name=>text}, :include => [{:container_inventory => {:container => [:size_type, :grade]}}, :company, :truck, :hauler]}}
    

    这应该允许您只包含和过滤一个命名范围。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多