2012-08-10 24 views
13

Czy ktoś może wyjaśnić, co robi ta metoda i co mogę do niej dodać?Scoped i zakres w szynach

scoped(options = nil) 
Returns an anonymous scope. 

A także co robi metoda zasięgu? Nie rozumiem po przeczytaniu dokumentacji.

Odpowiedz

30

W ActiveRecord, wszystkie metody budowania zapytań (np where, order, joins, limit i tak dalej) zwracają tzw zakresu. Tylko wtedy, gdy wywołasz metodę kicker taką jak all lub first, kwerenda wbudowana jest wykonywana i zwracane są wyniki z bazy danych.

Metoda klasy scoped również zwraca zakres. Zwrócony zasięg jest domyślnie pusty, co oznacza, że ​​zestaw wyników nie zostanie ograniczony w żaden sposób, co oznacza, że ​​wszystkie rekordy zostaną zwrócone, jeśli zapytanie zostało wykonane. Możesz go użyć do zapewnienia "pustej" alternatywy, takiej jak w przykładzie MurphoX, na przykład query_by_date. Można go używać do łączenia wielu warunków w jednym wywołaniu metody, jak na przykład:

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

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

scope metoda klasy pozwala definiować metody klasy, które również zwraca zakres, jak na przykład:

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

które mogą być używane tak:

Model.colored 

Dobrą rzeczą jest to, że z zakresów można je połączyć (prawie) jak chcesz, więc po to absolutnie możliwe:

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

ja również silnie sugerują czytania http://guides.rubyonrails.org/active_record_querying.html

+0

Dzięki severin, pomogło. Skąd mam wiedzieć, co mogę przekazać do .scoped? Rozumiem: warunki => itd. – LuckyLuke

+1

Znajdziesz tu pełną listę wszystkich opcji: http://api.rubyonrails.org/klasses/ActiveRecord/FinderMethods.html#method-i-find-label-Options – severin

+0

Awesome ! Dziękuję za pomoc – LuckyLuke

5

Użyłem go w past.When dokonać połączonych była wywołań interfejsu ActiveRecord kwerendy tak:

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

Każdy z nich jest już scoped, czyniąc pracę łańcucha bez żadnych problemów. Ale powiedzmy, że masz coś takiego:

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 
} 

To spowoduje błąd, jeśli data param nie jest dziś lub jutro. Wybrałby on ostatnią wartość i spróbuje połączyć tę kwerendę z następną wartością: query_by_user, co daje w wyniku undefined method default_scoped? for ''. Ale jeśli umieścisz metodę scoped w stanie else, będzie działał bez żadnych błędów, ponieważ mówisz do activerecord, że przechodzisz przez tę metodę/zakres nazwany i nie wykonywałeś żadnych połączeń z where/find/other activerecord methods, ale zwróciłeś obiekt o określonym zakresie, dzięki czemu możesz kontynuować łączenie zapytań i innych rzeczy.
Tak będzie na końcu.

else 
    scoped 
end 

Mam nadzieję, że rozumiesz ten prosty przykład.

+0

mógłby pan wyjaśnić, co to znaczy być „scoped”? – LuckyLuke

+1

To jest jak "bycie" zgodnym z ActiveRecord. Zawiera wszystkie specyfikacje ActiveRecords. – MurifoX

+0

Nie jestem pewien, czy rozumiem "zasięg" innych niż to, że rozumiem, co masz na myśli ... to znaczy, widzę, że inaczej zawiedzie. Ale nie rozumiem, co może zrobić i jakie jest "zakres". – LuckyLuke