Как выполнить сложный запрос Arel в Rails 3 из Model - PullRequest
3 голосов
/ 08 августа 2010

Я на Rails 3, и у меня есть SQL-запрос, состоящий из нескольких объединений, которые я создал в Arel.Я хочу выполнить этот запрос из метода в одной из моих моделей, но я не уверен, как это сделать.Оказывается, объект arel имеет тип Arel :: InnerJoin, и я хочу получить массив всех объектов, возвращенных из этого запроса.Запустить ли ModelName.find_by_sql (my_arel_query_object) для этого?Или я запускаю my_arel_query_object.each {...} и перебираю каждый кортеж, чтобы вручную вставить их в массив?

Надеюсь, я проясняю.Любое понимание будет с благодарностью.Спасибо.

Обновлено: вот код, который я использую в своей модели пользователя:

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

Я пытаюсь сделать так, чтобы все ингредиенты использовались во всех блюдах, предлагаемых для каждого.ресторан принадлежит пользователю.Переменная components_for_user представляет запрос Arel, который я хочу выполнить.Я просто не знаю, как запустить и вернуть все ингредиенты, а Ingredient.find_by_sql ... просто не выглядит правильным.

end

Ответы [ 3 ]

0 голосов
/ 12 сентября 2011

Я не понимаю, почему ты не сделал бы следующее.,,

Ingredient.joins({:meals=>:restaurants}).
           where(["restaurants.user_id = ?",self.id])
0 голосов
/ 18 мая 2012

Методы, которые возвращают объекты (например, ваш get_all_ingredients метод), должны быть методами класса.На 100% не очевидно, как это сделать в Ruby, но одним из способов является использование префикса self. при объявлении вашего метода.(Это self. имеет смысл в конце концов, когда вы погрузитесь в то, что рубисты часто называют 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 %>

0 голосов
/ 08 августа 2010

Объекты 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 %>

Пример взят из README Арела , который может помочь вам лучше понять.

...