2012-02-16 13 views
8

¿Hay alguna forma de tener nombres de columna de escritura ARel (desinfectados, posiblemente con alias, etc.) en CONCAT() y otras funciones SQL?¿Cómo uso funciones como CONCAT(), etc. en ARel?

Aquí es how to do it with AVG() ...

?> name = Arel::Attribute.new(Arel::Table.new(:countries), :name) 
=> #<struct Arel::Attributes::Attribute [...] 
?> population = Arel::Attribute.new(Arel::Table.new(:countries), :population) 
=> #<struct Arel::Attributes::Attribute [...] 
?> Country.select([name, population.average]).to_sql 
=> "SELECT `countries`.`name`, AVG(`countries`.`population`) AS avg_id FROM `countries`" 

(sí, ya sé que avg_id sería la misma en cada fila, tratando de ilustrar mi pregunta)

Entonces, ¿qué si quería una función diferente ?

?> Country.select(xyz).to_sql # Arel::Concat.new(name, population) or something? 
=> "SELECT CONCAT(`countries`.`name`, ' ', `countries`.`population`) AS concat_id FROM `countries`" 

¡Gracias!

+0

Sequel tiene una forma de seleccionar las columnas como ' "..." significa lit' 'SQL literal' en lugar de ser interpretado como una cadena de situaciones como esta.. Eso inhabilita el escape SQL para que pueda inyectar lo que quiera. No estoy seguro de cuál es el equivalente de AREL, pero tal vez sea una idea. – tadman

+0

He escrito un poco más de detalle aquí yo

Respuesta

12

Uso NamedFunction:

name = Arel::Attribute.new(Arel::Table.new(:countries), :name) 
func = Arel::Nodes::NamedFunction.new 'zomg', [name] 
Country.select([name, func]).to_sql 
+1

Parece que NamedFunction necesita estar adjunto a un atributo? p.ej. si quiero agrupar elementos por fechas, ¿podría hacer '.group (arel_table [: created_at] .date)', sin asociar la función "date" directamente en "created_at" para poder reutilizarlo en otro lugar? (sql: 'GROUP BY DATE (created_at)') –

+5

@ AaronPatterson Usando su código, 'func.to_sql' da' zomg ('countries', 'name') '. Creo que el código debería ser '... Function.new 'zomg', [name]' (con corchetes). – RocketR

Cuestiones relacionadas