2012-01-15 2 views
1

Я пытаюсь выбрать несколько столбцов после соединения. Я не мог найти способ сделать это с помощью ActiveRecord без написания SQL между кавычками в запросе (Thing, которого я бы хотел избежать)Присоединиться и выбрать несколько столбцов

Изучение Arel, я нашел, что я мог бы выбрать несколько столбцов, используя «проект», , однако я не совсем уверен, должен ли я использовать Arel напрямую или если бы был способ достичь того же AR.

Это является код в Arel:

l = Location.arel_table 
r = Region.arel_table 

postcode_name_with_region_code = l.where(l[:id].eq(location_id)).join(r).on(l[:region_id].eq(r[:id])).project(l[:postcode_name], r[:code]) 

После выполнения этого запроса я хотел бы вернуть что-то вдоль линий: (Псевдо-код)

"#{:postcode_name}, #{:code}" 
  1. Есть ли способ достичь одного и того же запроса с помощью AR?
  2. Если я придерживаюсь Arel, как я могу получить значения из класса SelectManager, возвращаемый выше запрос возвращается.

Спасибо заранее,

ответ

0

Использование AR, без написания SQL и предполагая, ваши модели и ассоциации являются:

модели/region.rb

class Region < ActiveRecord::Base 
    has_many :locations 
end 

модель/location.rb

class Location < ActiveRecord::Base 
    belongs_to :region 
end 

Вы, безусловно, можете сделать:

postcode_name_with_region_code = Location.where(:id=>location_id).includes(:region).collect{|l| "#{l.postcode_name}, #{l.region.code}"} 

Это будет делать запрос, а затем использовать рубин для форматирования результата (обратите внимание, что он будет возвращать массив, так как я предполагаю, что там может быть несколько записей возвращается). Если вам нужен только один элемент массива, вы можете использовать метод array.first для его ссылки.

Вы могли бы также хотели ТЕПЛОВОЙ НАГРУЗКИ ассоциации и строить свою строку из результата:

my_loc = Location.find(location_id, :include=>:region) 

postcode_name_with_region_code = "#{my_loc.postcode_name}, #{my_loc.region.code}" 
+0

Спасибо Майк для вас ответ. Это еще один вопрос, с точки зрения производительности, не было бы более эффективным для объединения, а не включения? Это может быть не так сильно, как в случае с этим запросом, но я видел, что он дважды запрашивает БД при использовании. – Digger

+0

Соединения на самом деле ничего не поймут в этом случае. Если вы хотите попробовать, замените .includes (...) на .joins ("JOIN locations.region_id ON regions.id"). Второй запрос является результатом запроса на сборку, запрашивающего код региона. Я добавил решение, которое использует AR-загрузку ассоциации, если вы хотите попробовать эту попытку. – miked

+0

Спасибо, я отдам. После небольшого воспроизведения с AR это был запрос, который я начал использовать: 'Location.joins (: region) .where (: id => location_id) .select ('locations.postcode_name, regions.code') .map {| л | "# {l.postcode_name}, # {l.code}"} ' – Digger

0
predicate = Location.where(:id=>location_id).includes(:region) 
predicate.ast.cores.first.projections.clear 
predicate.project(Location.arel_table[:postcode_name], Region.arel_table[:code]) 

 Смежные вопросы

  • Нет связанных вопросов^_^