2011-06-26 31 views
2

是否可以通過Hash作爲ActiveRecordselect的參數?我的意思是這樣的(在這裏我簡單的模型:LineItemid「的Product S和Order):散列用於ActiveRecord的選擇

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

得到以下SQL:

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方法,但我不知道如何使其作爲透明(即w/o _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 

我會感激約ActiveRecord的實現內部的一些細節指點我關於它是被用來做這個非常obscure-模式到考試寶石:)

回答

1

選擇method--

# 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

我不知道這會有所幫助,但起碼它可能會送你在正確的方向去探索......

+0

片段顯示'select'的模塊主要是爲了測試目的而設計的:'select'使用一個塊從相應的表中提取所有行(通過詳盡的'SELECT * FROM table')到一個數組中並應用'數組#選擇它,因此使用Ruby語言而不是SQL來過濾它。 – jdoe

+0

是的,這聽起來是正確的。 – jaydel