2010-09-17 14 views
8

DadoArel, cómo se unen

class Category < ActiveRecord::Base 
    has_many :products, :order => 'name ASC' 
end 

El uso de los carriles 3 pila, ¿cómo es posible consultar el I para todas las categorías que tienen '' productos?

Respuesta

13
Category.joins(:products).select("distinct categories.*").all 
+0

Eso funcionó, genial gracias. – Jan

+0

¿Conoces una buena referencia sobre lo que es posible con las consultas arel? – Jan

+0

Utilizo mi conocimiento de Google leyendo blogs de Rails-elite. Lo importante: ActiveRecord difiere mucho de Arel puro. – gertas

26

En Arel (NO ActiveRecord) vamos a hacer lo siguiente:

p = Arel::Table.new :products # Base Rel-var 
c = Arel::Table.new :categories # Base Rel-var 

predicate = p[:category_id].eq(c[:id]) # for equality predicate 

p.join(c)     # Natural join 
    .on(predicate)   # Equi-Join 
    .group(p[:category_id]) # Grouping expression to get distinct categories 
    .project(c[:id])  # Project the distinct category IDs of the derived set. 
+0

Cuando dice "En ARel (NO ActiveRecord)", ¿a qué se refiere exactamente? ¿Que no podemos hacer esto en una clase derivada de 'ActiveRecord :: Base'? Esto es confuso. –

+0

Puede usar Arel in Rails. Está incluido por supuesto. –

+27

En todos estos ejemplos, nunca veo el paso final doblando la consulta AREL a Rails para obtener registros reales. ¿Qué hacer con p ahora? Puede llamar a toqsql con seguridad pero ¿cómo convertirlo en una Relación ActiveRecord :: que cargará registros? – bradgonesurfing

1

Otro, más simple, el enfoque es el uso de join conjuntamente con Arel para la sentencia condicional la interfaz de consulta ActiveRecord:

joins(:user) 
.where(User.arel_table[:name].matches("%#{query}%")) 

genera el siguiente código SQL en sqlite3:

"SELECT \"patients\".* FROM \"patients\" INNER JOIN \"users\" ON \"users\".\"id\" = \"patients\".\"user_id\" WHERE (\"users\".\"name\" LIKE '%query%')" 

Y el siguiente código SQL en Postgres (nótese la ILIKE):

"SELECT \"patients\".* FROM \"patients\" INNER JOIN \"users\" ON \"users\".\"id\" = \"patients\".\"user_id\" WHERE (\"users\".\"name\" ILIKE '%query%')" 

Esto permite que se conecten con sencillez, pero aún así obtener la abstracción del matcher Arel a su RDBMS.

Cuestiones relacionadas