如何在返回之前修改Rails ActiveRecord查询结果?

时间:2011-06-06 20:54:54

标签: ruby-on-rails activerecord

我有一个数据表,需要在运行时通过外部服务的其他数据进行更新。我想做的是这样的事情:

MyModel.some_custom_scope.some_other_scope.enhance_with_external_data.each do |object|
  puts object.some_attribute_from_external_data_source
end

即使我不能使用这种确切的语法,我希望最终结果能够尊重我可能使用的任何范围。我试过这个:

def self.enhance_with_external_data
  external_data = get_external_data
  Enumerator.new do |yielder|
    # mimick some stuff I saw in ActiveRecord and don't quite understand:
    relation.to_a.each do |obj|
      update_obj_with_external_data(obj)
      yielder.yield(obj)
    end
  end
end

这主要是有效的,除了它不尊重以前应用的任何范围,所以如果我这样做:

MyModel.some_custom_scope.some_other_scope.enhance_with_external_data

它返回所有MyModel,而不仅仅是some_custom_scope和some_other_scope范围内的那些。

希望我想要做的事情是有道理的。任何人都知道怎么做,或者我想把一个方形钉挂在圆孔里?

2 个答案:

答案 0 :(得分:2)

我找到了一种方法来做到这一点。有点难看,但似乎有用:

def self.merge_with_extra_info
  the_scope = scoped
  class << the_scope
    alias :base_to_a :to_a
    def to_a
      MyModel.enhance(base_to_a)
    end
  end
  the_scope
end

def self.enhance(items)
  items.each do |item|
    item = add_extra_item_info(item)
  end
  items
end

这样做是为我的模型添加一个类方法 - 由于我不知道的原因似乎也使它可用于ActiveRecord :: Relation实例。它仅覆盖当前作用域对象的to_a方法,该方法被调用以获取记录。这让我可以在返回之前为每条记录添加额外的信息。所以现在我获得了所有的可连接性和所有类似的东西:

MyModel.where(:some_attribute => some_value).merge_with_extra_info.limit(10).all

我希望能够得到它,因为它被枚举,而不是像这里放入一个阵列,但无法弄清楚如何深入AR / Arel。

答案 1 :(得分:0)

通过扩展关系,我实现了与此相似的东西:

@media screen and (min-width: 760px) and (max-width: 980px) {

  #features .main-links {
    width: 100%;
    border: solid 2px red;
  }

  #features li {
    border: solid 2px lime;
    width: 100%;
    display: block;
  }


  .contact-info {
    display: none;
  }
}