Domyślna kolejność sortowania dla modelu rails?
Chciałbym określić domyślną kolejność sortowania w moim modelu.
Tak, że gdy robię .where()
bez podania .order()
używa domyślnego sortowania. Ale jeśli podam .order()
, nadpisuje domyślną wartość.
3 answers
default_scope
To działa dla Rails 4+:
class Book < ActiveRecord::Base
default_scope { order(created_at: :desc) }
end
W przypadku Rails 2.3, 3 potrzebujesz tego zamiast tego:
default_scope order('created_at DESC')
Dla Rails 2.x:
default_scope :order => 'created_at DESC'
Gdzie created_at
jest polem, na którym ma być wykonane domyślne sortowanie.
Uwaga: ASC jest kodem używanym do wstępowania i DESC jest dla malejących (desc
, nie dsc
!).
scope
Kiedy już się do tego przyzwyczaisz, możesz również użyć scope
:
class Book < ActiveRecord::Base
scope :confirmed, :conditions => { :confirmed => true }
scope :published, :conditions => { :published => true }
end
Do Rails 2 potrzebujesz named_scope
.
:published
scope daje Book.published
zamiast
Book.find(:published => true)
.
Od Rails 3 możesz' połączyć ' te metody ze sobą, łącząc je z okresami między nimi, więc z powyższymi zakresami możesz teraz używać Book.published.confirmed
.
W przypadku tej metody zapytanie nie jest faktycznie wykonywane, dopóki nie są potrzebne rzeczywiste wyniki( leniwa ocena), więc 7 zakresów może być połączonych łańcuchowo, ale tylko w wyniku 1 rzeczywistego zapytania bazy danych, aby uniknąć problemy z wydajnością po wykonaniu 7 oddzielnych zapytań.
Możesz użyć parametru passed in, takiego jak date lub user_id (coś, co zmieni się w czasie wykonywania, a więc będzie wymagało 'leniwej oceny', z lambda, jak to: {27]}
scope :recent_books, lambda
{ |since_when| where("created_at >= ?", since_when) }
# Note the `where` is making use of AREL syntax added in Rails 3.
W końcu możesz wyłączyć domyślny zakres za pomocą:
Book.with_exclusive_scope { find(:all) }
Albo jeszcze lepiej:
Book.unscoped.all
Który wyłączy dowolny filtr (warunki) lub sortowanie (kolejność według).
zauważ, że pierwsza wersja działa w Rails2+, podczas gdy drugi (bez znaku) jest tylko dla szyn 3 +
Więc
... jeśli myślisz, hmm, więc to są takie same metody... dokładnie tym są te lunety!
Są jak posiadanie def self.method_name ...code... end
, ale jak zawsze w ruby są to ładne małe skróty składniowe (lub "cukier"), aby ułatwić Ci życie!
W rzeczywistości są to metody na poziomie klasy, ponieważ działają na 1 zbiorze' wszystkich ' rekordów.
Ich format zmienia się jednak Z rails 4 podczas używania #scope, bez przekazywania obiektu wywołującego, są ostrzeżenia o wycofaniu. na przykład scope: red, where (color: 'red') należy zmienić na scope :red, -> { where(color: 'red') }
.
Na marginesie, w przypadku nieprawidłowego użycia, default _scope może być nadużywane/nadużywane.
Chodzi głównie o to, kiedy jest używany do działań takich jak where
ograniczanie (filtrowanie) wyboru default (a zły pomysł dla domyślnej), a nie tylko do porządkowania wyników.
Dla where
zaznaczenia, wystarczy użyć zwykłych nazwanych zakresów. i dodać ten zakres w zapytaniu, np. Book.all.published
gdzie published
jest nazwanym zakresem.
Podsumowując, lunety są naprawdę świetne i pomagają wprowadzić rzeczy do modelu suszarki "fat model thin controller".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-02 15:42:38
Szybka aktualizacja do doskonałej odpowiedzi Michaela powyżej.
Dla Rails 4.0 + musisz umieścić swój sort w takim bloku:
class Book < ActiveRecord::Base
default_scope { order('created_at DESC') }
end
Zwróć uwagę, że polecenie jest umieszczone w bloku oznaczonym nawiasami klamrowymi.
Zmienili go, ponieważ zbyt łatwo było przejść w coś dynamicznego (jak obecny czas). Usuwa to problem, ponieważ blok jest oceniany w czasie wykonywania. Jeśli nie użyjesz bloku, otrzymasz ten błąd:
Wsparcie dla wywołania # default_scope bez bloku jest usuwany. Na przykład zamiast
default_scope where(color: 'red')
Użyjdefault_scope { where(color: 'red') }
. (Alternatywnie możesz po prostu przedefiniować siebie.default_scope.)
Jako @Dan wspomina w swoim komentarzu poniżej, możesz zrobić bardziej rubyish składni jak to:
class Book < ActiveRecord::Base
default_scope { order(created_at: :desc) }
end
Lub z wieloma kolumnami:
class Book < ActiveRecord::Base
default_scope { order({begin_date: :desc}, :name) }
end
Thanks @Dan!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:26
Możesz użyć default_scope, aby zaimplementować domyślny porządek sortowania http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-18 22:19:30