2010-08-08 42 views
2

在Rails 3中執行復雜的Arel查詢我在Rails 3上,並且我有一個SQL查詢由我在Arel中構建的一些連接組成。我想在我的模型中的某個方法中運行此查詢,但我不確定如何執行此操作。 arel對象結果是Arel :: InnerJoin的類型,我想要檢索從該查詢返回的所有對象的數組。我是否運行ModelName.find_by_sql(my_arel_query_object)來執行此操作?或者,我運行my_arel_query_object.each {...}並迭代每個元組以手動將它們彈出到數組中?如何從Model

我希望我能讓自己清楚。任何有識之士將不勝感激。謝謝。

更新:這裏是我我的用戶模型中使用的代碼:

def get_all_ingredients 
    restaurants = Table(:restaurants) 
    meals = Table(:meals) 
    ingredients = Table(:ingredients) 

    restaurants_for_user = restaurants.where(restaurants[:user_id].eq(self.id)) 
    meals_for_user = restaurants_for_user.join(meals).on(restaurants[:id].eq(meals[:restaurant_id])) 
    ingredients_for_user = meals_for_user.join(ingredients).on(meals[:id].eq(ingredients[:meal_id])) 

    return Ingredient.find_by_sql(ingredients_for_user.to_sql) 
end 

我想在這裏做的就是在每個餐館的用戶擁有所提供的所有餐點使用的所有成分。 ingredients_for_user變量表示我希望運行的Arel查詢。我只是不知道如何運行&返回所有的成分,而Ingredient.find_by_sql ...似乎並不正確。

+0

請出示碼您目前必須生成查詢。 – 2010-08-08 05:53:16

+0

我剛將它添加到我的文章。 – pushmatrix 2010-08-08 16:00:26

+0

@pushmatrix你怎麼解決這個問題? – squiter 2013-06-13 13:13:40

回答

-1

阿雷爾對象(或者更具體地,Arel::Relation對象)表示在關係代數查詢。在您第一次嘗試訪問其元素時執行查詢,並像以前一樣充當結果集。

舉例來說,如果你有一個像

users.join(:photos).on(users[:id].eq(photos[:user_id])) 

查詢就可以了,遍歷照片視圖:

<% users.each do |user| %> 
    <% users.photos.each do |photo| %> 
    <%= photo.name %> 
    <% end %> 
<% end %> 

的例子來自Arel's README拍攝,這可以幫助你更好地理解。

+0

你的第一個代碼示例中有一個小的錯字,它不應該是照片上的冒號。另外,我不確定你在做第二個例子。 Arel :: Table的類型是「用戶」還是「照片」? – pushmatrix 2010-08-08 04:49:22

+1

'未定義的方法'每個'用於# 2014-10-05 22:49:47

0

我不明白你爲什麼不做以下操作。 。 。

Ingredient.joins({:meals=>:restaurants}). 
      where(["restaurants.user_id = ?",self.id]) 
+0

因爲不能保證以這種方式在複雜查詢中使用索引。 – Slotos 2011-11-11 15:05:48

+4

索引與arel-rails不會與查詢計劃程序進行交互(除了僅生成基於字符串的sql語句)無關。 – klochner 2011-11-11 17:32:16

+0

索引與性能有關。獲得10ms與800ms的查詢時間很重要。你必須關心這一點。 I.e.在PostgreSQL中,在ON語句中注入過濾器將優化用於過濾_before_ join的查詢。在我的情況下顯着減少數據集的大小。將它放入WHERE將在邏輯上沒有索引的巨大結果數據集上運行過濾器。所以是的,鐵軌與規劃師互動。它提交查詢。 – Slotos 2011-11-13 03:26:02

-1

返回對象的方法(如您的get_all_ingredients方法)應該是類方法。在Ruby中如何做到這一點並不是100%,但是一種方法是在聲明方法時使用前綴self.。 (這個self.最終是有意義的,當你潛入Rubyists經常稱之爲eigenclass的時候,但現在我們可以知道這是如何完成的)。

這是你的方法應該是什麼樣子在你的配料模式:

def self.get_all_ingredients 
    # insert your code from your question here 
end 

然後打電話給你的方法,你的觀點一樣:

<%- Ingredients.get_all_ingredients.each do |current_ingredient| %>
# do your things here
<% end %>