2010-08-08 2 views
2

레일 3을 사용 중이며 Arel에서 빌드 한 몇 개의 조인으로 구성된 SQL 쿼리가 있습니다. 내 모델 중 하나의 메서드에서이 쿼리를 실행하고 싶지만이 작업을 수행하는 방법을 잘 모르겠습니다. arel 개체는 Arel :: InnerJoin 유형으로 밝혀졌으며 해당 쿼리에서 반환 된 모든 개체의 배열을 검색하려고합니다. 그렇게하기 위해 ModelName.find_by_sql (my_arel_query_object)을 실행합니까? 아니면 my_arel_query_object.each {...}를 실행하고 배열로 수동으로 팝하기 위해 각 튜플을 반복합니까?레일즈 3에서 복잡한 Arel 쿼리를 실행하는 방법

나는 분명히하고 싶다. 어떤 통찰력이라도 대단히 감사하겠습니다. 감사.

업데이트 :

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

코드를 보여주십시오

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

다음처럼보기에서 메소드를 호출 현재 쿼리를 생성해야합니다. –

+0

방금 ​​내 글에 추가했습니다. – pushmatrix

+0

@ pushmatrix 어떻게이 문제를 해결할 수 있습니까? – squiter

답변

-1

Arel 객체 (또는, 더 구체적으로, 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

+1

'

0

나는 왜 당신이 다음을하지 않을지 이해하지 못합니다. . .

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

이렇게하면 복잡한 쿼리에서 인덱스를 사용할 수 없기 때문입니다. – Slotos

+4

인덱스는 문자열 기반 SQL 문을 생성하는 것 외에는 쿼리 플래너와 상호 작용하지 않습니다. – klochner

+0

인덱스는 성능과 관련이 있습니다. 10ms 대 800ms의 쿼리 시간은 중요합니다. 당신은 그것에 대해 신경써야합니다. I. PostgreSQL의 경우 ON 문에 필터를 삽입하면 _before_ join 필터링에 대한 쿼리가 최적화됩니다. 필자의 경우 데이터 세트 크기를 크게 줄였습니다. 논리적으로 인덱스가없는 거대한 결과 데이터 집합에 대해 필터를 WHERE으로 실행합니다. 예, 레일은 플래너와 상호 작용합니다. 쿼리를 제출합니다. – Slotos

-1

개체를 반환하는 메서드 (예 : get_all_ingredients 메서드)는 클래스 메서드 여야합니다. Ruby에서이를 수행하는 방법은 100 % 확실하지 않지만, 한 가지 방법은 메서드 선언시 self. 접두어를 사용하는 것입니다. (이 self.은 Rubyists가 종종 eigenclass이라고 부르는 것을 들여다 보면 이해할 수 있습니다. 그러나 지금은 그것이 완료된 것임을 알 수 있습니다).

여기에 귀하의 방법은 당신의 성분 모델과 같아야 작업은 다음과 같습니다

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