Hash for ActiveRecord的选择

时间:2011-06-26 16:23:57

标签: ruby-on-rails activerecord

是否可以将Hash作为ActiveRecord select的参数传递?我的意思是这样的(这里我有简单的模型:LineItemid的{​​{1}}和Product}:

Order

获取以下SQL:

Product.select(
    :orders => [{:name => :buyer}, :email], # orders.name as buyer
    :products => {:title => :product}).     # products.title as product
  joins(:line_items => :order)

如果不可能,那么我建议SELECT "orders"."name" as "buyer", "orders"."email", "products"."title" as "product" FROM "products" INNER JOIN "line_items" ON "line_items"."product_id" = "products"."id" INNER JOIN "orders" ON "orders"."id" = "line_items"."order_id" 方法的一些向后兼容(可以旧方式使用,1个简单字符串作为peremeter)扩展,但我无法弄清楚如何将其作为透明(即最后没有select,如下所示)应用程序范围的替换:

_h

我很感激地向我指出一些关于class ActiveRecord::Base def self.select_h(*fields) # TODO: rid of this ugly _h hash_of_fields = fields.last.is_a?(Hash) ? fields.pop : {} fields_in_hash = hash_of_fields.map do |table, field_or_fields| (field_or_fields.is_a?(Array) ? field_or_fields : [field_or_fields]).map do |field| field = "#{field.first[0]}\" as \"#{field.first[1]}" if field.is_a? Hash "\"#{table}\".\"#{field}\"" end end # calling original select select (fields+fields_in_hash).join(', ') end end 实施的内部细节的一些细节,这些细节用于制作这个非常模糊的考试宝石:)

2 个答案:

答案 0 :(得分:1)

选择方法的来源 -

# File activerecord/lib/active_record/relation/query_methods.rb, line 34
def select(value = Proc.new)
  if block_given?
    to_a.select {|*block_args| value.call(*block_args) }
  else
    relation = clone
    relation.select_values += Array.wrap(value)
    relation
  end
end

- 表明它不会做你要求的。但是,因为它可以选择一个块,你可能会强迫它进入你正在寻找的行为......

每当我对Arel的东西感到困惑时,我只会仔细阅读来源:

Arel API

我不确定这有什么帮助,但至少它可能会让你朝着正确的方向探索......

答案 1 :(得分:0)

关于如何避免_h的最后一个问题,请参阅When monkey patching a method, can you call the overridden method from the new implementation?

class Foo
  def bar
    'Hello'
  end
end 

class Foo
  old_bar = instance_method(:bar)

  define_method(:bar) do
    old_bar.bind(self).() + ' World'
  end
end

Foo.new.bar # => 'Hello World'