是否可以将Hash
作为ActiveRecord
select
的参数传递?我的意思是这样的(这里我有简单的模型:LineItem
有id
的{{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
实施的内部细节的一些细节,这些细节用于制作这个非常模糊的考试宝石:)
答案 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的东西感到困惑时,我只会仔细阅读来源:
我不确定这有什么帮助,但至少它可能会让你朝着正确的方向探索......
答案 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'