2008-09-26 6 views
9

Me preguntaba si había una forma de usar "find_by_sql" dentro de un named_scope. Me gustaría tratar sql personalizado como named_scope para que pueda encadenarlo a mis existing_scopes existentes. También sería bueno para optimizar un fragmento de sql que utilizo con frecuencia.Encapsulando SQL en un named_scope

Respuesta

10

Si bien se puede poner cualquier SQL que te gusta en las condiciones de un ámbito con nombre, si a continuación, llama a find_by_sql entonces los 'ámbitos 'ser tirado.

Dado:

class Item 
    # Anything you can put in an sql WHERE you can put here 
    named_scope :mine, :conditions=>'user_id = 12345 and IS_A_NINJA() = 1' 
end 

Esto funciona (que sólo se pega la cadena SQL ahí - si usted tiene más de un consiguen unieron con Y)

Item.mine.find :all 
=> SELECT * FROM items WHERE ('user_id' = 887 and IS_A_NINJA() = 1) 

Sin embargo, esto no lo hace

Items.mine.find_by_sql 'select * from items limit 1' 
=> select * from items limit 1 

Así que la respuesta es "No". Si piensas en lo que debe suceder detrás de las escenas, entonces tiene mucho sentido. Para construir los raíles SQL tiene que saber cómo encaja.
Cuando crea consultas normales, select, joins, conditions, etc. se dividen en distintas partes. Rails sabe que puede agregar cosas a las condiciones sin afectar a todo lo demás (que es cómo funcionan with_scope y named_scope).

Sin embargo, con find_by_sql, le da a los rieles una cuerda grande. No sabe qué es lo que pasa, por lo que no es seguro que entre y agregue las cosas que necesitaría agregar para que los ámbitos funcionen.

0

seguro de por qué no

: named_scope: condiciones => [SQL]

1

Esto no trata exactamente sobre lo que preguntaste, pero podrías investigar 'contruct_finder_sql'. Le permite obtener el SQL de un alcance con nombre.

named_scope :mine, :conditions=>'user_id = 12345 and IS_A_NINJA() = 1' 
named_scope :additional { 
    :condtions => mine.send(:construct_finder_sql,{}) + " additional = 'foo'" 
} 
Cuestiones relacionadas