Подтвердить что ты не робот

Как можно загружать объекты с помощью пользовательского соединения в рельсах?

Фон

Обычная рельсовая загрузка коллекций работает следующим образом:

Person.find(:all, :include=>:companies)

Это генерирует некоторый sql, который делает

LEFT OUTER JOIN companies ON people.company_id = companies.id

Вопрос

Однако мне нужно настраивать соединение (это также может возникнуть, если я использовал find_by_sql), поэтому я не могу использовать vanilla :include => :companies

Пользовательское соединение /sql доставит мне все нужные мне данные, но как я могу сообщить activerecord, что он принадлежит связанным объектам Company, а не просто быть кучей дополнительных строк?

Update

Мне нужно добавить дополнительные условия в соединение. Что-то вроде этого:

SELECT blah blah blah
LEFT OUTER JOIN companies ON people.company_id = companies.id AND people.magical_flag IS NULL 
<Several other joins>
WHERE blahblahblah
4b9b3361

Ответ 1

Не можете ли вы добавить условия соединения с помощью ActiveRecord?

Например, у меня довольно сложный запрос с использованием нескольких зависимых записей, и он отлично работает, комбинируя условия и включающие директивы

Contractors.find(
  :all, 
  :include => {:council_areas => :suburbs},
  :conditions => ["suburbs.postcode = ?", customer.postcode]                 
)    

Предполагая, что:

  • Подрядчики have_many CouncilAreas
  • СоветAreas have_many Suburbs

Это объединение возвращает Подрядчиков в пригороде, обозначенных customer.postcode.

Сгенерированный запрос выглядит так:

SELECT contractors.*, council_areas.*, suburbs.*
FROM `contractors` 
LEFT OUTER JOIN `contractors_council_areas` ON `contractors_council_areas`.contractor_id = `contractors`.id 
LEFT OUTER JOIN `council_areas` ON `council_areas`.id = `contractors_council_areas`.council_area_id 
LEFT OUTER JOIN `council_areas_suburbs` ON `council_areas_suburbs`.council_area_id = `council_areas`.id 
LEFT OUTER JOIN `suburbs` ON `suburbs`.id = `council_areas_suburbs`.suburb_id WHERE (suburbs.postcode = '5000')

(Примечание: я сократил список столбцов для краткости).

Ответ 2

Вы можете использовать что-то вроде следующего, чтобы получить синтаксическую магию левого внешнего соединения.

Person.reflect_on_association(:companies).options[:conditions] = 'people.magical_flag IS NULL'

Ответ 3

Я не уверен, что вы хотите (я не уверен на 100%, что понял ваш вопрос и что вы хотите выполнить), но:

Как обеспечить как :joins, так и :includes?

Person.find( :all, :joins => 'LEFT OUTER JOIN companies ON people.company_id = companies.id AND _pass_custom_conditions_here_', :includes => :companies )

Или способ AR3:

Person.includes(:companies).joins('LEFT OUTER JOIN companies ON people.company_id = companies.id AND _pass_custom_conditions_here_')

Ответ 4

Можете ли вы подробнее рассказать о том, что вы пытаетесь выполнить с помощью этого запроса?

Также взгляните на параметр: join для поиска. Он позволяет указать, как вы хотите, чтобы таблицы были соединены. текст ссылки

И будьте осторожны при использовании: include, поведение немного изменится в Rails 2.1 и может вызвать некоторые проблемы при использовании в сочетании с опцией: условия, которая ссылается на включенную таблицу. текст ссылки и ссылка текст - это две статьи из Pivotal, в которых упоминается эта информация.