sql - query - rails joins
Cómo impaciente cargar objetos con una unión personalizada en rieles? (4)
Fondo
Los rieles normales de carga ansiosa de colecciones funcionan así:
Person.find(:all, :include=>:companies)
Esto genera algunos sql que hace
LEFT OUTER JOIN companies ON people.company_id = companies.id
Pregunta
Sin embargo, necesito una unión personalizada (esto también podría surgir si estuviera usando find_by_sql
) entonces no puedo usar el vainilla :include => :companies
La combinación personalizada / sql me proporcionará todos los datos que necesito, pero ¿cómo puedo decirle a activerecord que pertenece a los objetos asociados de la Company
lugar de ser un montón de filas adicionales?
Actualizar
Necesito poner condiciones adicionales en la unión. Algo como esto:
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
¿No puede agregar las condiciones de unión usando ActiveRecord?
Por ejemplo, tengo una consulta bastante compleja que usa varios registros dependientes y funciona bien al combinar condiciones e incluir directivas
Contractors.find(
:all,
:include => {:council_areas => :suburbs},
:conditions => ["suburbs.postcode = ?", customer.postcode]
)
Asumiendo que:
- Contratistas have_many CouncilAreas
- CouncilAreas have_many Suburbs
Esta unión devuelve los Contratistas en el suburbio identificado por customer.postcode .
La consulta generada se ve así:
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'')
(Nota: edité la lista de columnas para abreviar).
¿Puedes elaborar un poco más sobre lo que estás tratando de lograr con esta consulta?
También eche un vistazo a la opción: join para encontrar. Le permite especificar cómo quiere que se unan las tablas. Texto del enlace
Y tenga cuidado al usar: incluir, el comportamiento cambia un poco en Rails 2.1 y puede causar algunos problemas cuando se usa junto con una opción: conditions que hace referencia a una tabla incluida. el texto del enlace y el texto del enlace son dos artículos de Pivotal que mencionan este gotcha.
No estoy seguro de que sea lo que quieres (no estoy 100% seguro de haber entendido tu pregunta y lo que quieres lograr) pero:
¿Qué hay de proporcionar tanto :joins
como :includes
?
Person.find( :all, :joins => ''LEFT OUTER JOIN companies ON people.company_id = companies.id AND _pass_custom_conditions_here_'', :includes => :companies )
O AR3 manera:
Person.includes(:companies).joins(''LEFT OUTER JOIN companies ON people.company_id = companies.id AND _pass_custom_conditions_here_'')
Puede usar algo como lo siguiente para obtener la magia sintáctica de combinación externa izquierda apropiada.
Person.reflect_on_association(:companies).options[:conditions] = ''people.magical_flag IS NULL''