2012-08-10 18 views
13

¿Alguien puede explicarme qué hace este método y qué puedo transmitirle?Alcance y alcance en rieles

scoped(options = nil) 
Returns an anonymous scope. 

Y también lo que hace el método de alcance? No entiendo después de leer la documentación.

Respuesta

30

En ActiveRecord, todos los métodos de construcción de consultas (como where, order, joins, limit y así sucesivamente) Devuelve una llamada alcance. Solo cuando llama a un método kicker como all o first, la consulta acumulada se ejecuta y se devuelven los resultados de la base de datos.

El método de clase scoped también devuelve un alcance. El alcance devuelto es, por defecto, vacío, lo que significa que el conjunto de resultados no estaría restringido de ninguna manera, lo que significa que todos los registros se devolverían si se ejecutara la consulta. Puede usarlo para proporcionar una alternativa "vacía" como en el ejemplo query_by_date de MurifoX. O se puede utilizar para combinar varias condiciones en una llamada al método, como por ejemplo:

Model.scoped(:conditions => 'id < 100', :limit => 10, :order => 'title ASC') 

# which would be equivalent to 
Model.where('id < 100').limit(10).order('title ASC') 

El método de la clase scope le permite definir un método de clase que también devuelve un ámbito, como por ejemplo:

class Model 
    scope :colored, lambda {|col| 
    where(:color => col) 
    } 
end 

que puede ser utilizado como esto:

Model.colored 

lo bueno es que con ámbitos se pueden combinar (casi) como desee, por lo que el siguiente es absolutamente posible:

Model.red.where('id < 100').order('title ASC').scoped(:limit => 10) 

también sugieren fuertemente la lectura a través http://guides.rubyonrails.org/active_record_querying.html

+0

Gracias severin, ayudó. ¿Cómo sé a qué puedo pasarle a .scoped? Veo: conditions => etc. – LuckyLuke

+1

Aquí encontrarás una lista completa de todas las opciones: http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-find-label-Options – severin

+0

Awesome ! Gracias por su ayuda – LuckyLuke

5

lo he utilizado en el past.When permite hacer llamadas encadenado a la interfaz ActiveRecord consulta como esta:

Model.where(:conditions).where(:more_conditions).where(:final_conditions) 

Cada uno de ellos ya está en el ámbito, por lo que el trabajo en cadena sin ningún problema. Pero digamos que usted tiene algo como esto:

Model.query_by_date(date).query_by_user(user).query_by_status(status) 

scope :query_by_date, lambda { |date| 
    case date 
    when "today" 
    where(:date => Date.today) 
    when "tomorrow" 
    where(:date => Date.tomorrow) 
    else 
    # Any value like '' or 0 or Date.whatever 
    end 
} 

Esto provocaría un error si el parámetro fecha no es hoy o mañana. Seleccionaría el último valor e intentaría encadenar esta consulta con la siguiente query_by_user, lo que daría como resultado undefined method default_scoped? for ''. Pero si pone un método scoped en la condición else, funcionaría sin fallas, porque está diciendo a activerecord que pasa por este método/alcance especificado y no hizo ninguna llamada al where/find/other activerecord methods, sino que devolvió un objeto con ámbito, para que pueda continuar encadenando consultas y cosas.
Sería de esta manera al final.

else 
    scoped 
end 

Espero que comprenda este simple ejemplo.

+0

Podría explicar lo que significa ser "de ámbito"? – LuckyLuke

+1

Es como "ser" compatible con ActiveRecord. Encapsulado por todas las especificaciones de ActiveRecords. – MurifoX

+0

No estoy seguro si entiendo "con alcance" aparte de que entiendo lo que quiere decir ... es decir, veo que de lo contrario fallará. Pero no entiendo lo que el "alcance" puede hacer y es. – LuckyLuke