Wydaje się, że to naprawdę proste pytanie, ale nigdzie nie widziałem na nie odpowiedzi.
W szynach, jeśli masz:
class Article < ActiveRecord::Base
has_many :comments
end
class Comments < ActiveRecord::Base
belongs_to :article
end
Dlaczego nie możesz zamówić komentarzy za pomocą czegoś takiego:
@article.comments(:order=>"created_at DESC")
Nazwany zakres działa, jeśli potrzebujesz dużo odwołań do niego, a nawet ludzie robią takie rzeczy:
@article.comments.sort { |x,y| x.created_at <=> y.created_at }
Ale coś mi mówi, że powinno być prostsze. czego mi brakuje?
ruby-on-rails
Brian Armstrong
źródło
źródło
Odpowiedzi:
Możesz określić porządek sortowania dla czystej kolekcji, korzystając z opcji
has_many
samej:Lub, jeśli potrzebujesz prostej, niebazowej metody sortowania, użyj sort_by :
Zbierając to za pomocą metod zamawiania dodanych przez ActiveRecord:
Twój przebieg może się różnić: charakterystyka wydajności powyższych rozwiązań będzie się gwałtownie zmieniać w zależności od tego, w jaki sposób pobierasz dane i którego Rubiego używasz do uruchamiania aplikacji.
źródło
-> { order(created_at: :desc) }
Zamiast tego użyj lambdy . Zobacz: stackoverflow.com/questions/18284606/…Od Rails 4 zrobiłbyś:
W przypadku
has_many :through
relacji kolejność argumentów ma znaczenie (musi być druga):Jeśli zawsze będziesz chciał komentarzach dostępu w tej samej kolejności, bez względu na kontekst, można również zrobić to za pośrednictwem
default_scope
wewnątrzComment
jak:Jednak może to być problematyczne z powodów omówionych w tym pytaniu .
Przed Railsami 4 można było określić
order
jako klucz relacji, na przykład:Jak wspomniał Jim, możesz również użyć
sort_by
po pobraniu wyników, chociaż w każdym zestawie wyników o rozmiarze będzie to znacznie wolniejsze (i zużyje o wiele więcej pamięci) niż przy zamawianiu przez SQL / ActiveRecord.Jeśli robisz coś, w którym dodanie domyślnego zamówienia jest z jakiegoś powodu uciążliwe lub chcesz zastąpić domyślne w niektórych przypadkach, trywialne jest określenie tego w samej akcji pobierania:
źródło
.order()
do łańcucha metod, jak w ostatnim przykładzie. Czy o to pytasz?Jeśli używasz Railsów 2.3 i chcesz użyć tej samej domyślnej kolejności dla wszystkich kolekcji tego obiektu, możesz użyć default_scope do zamówienia swojej kolekcji.
Jeśli zadzwonisz
Zostaną one zamówione zgodnie z Twoim default_scope. TBH w bardzo ogólnym sensie porządkowanie jest jedynym naprawdę dobrym zastosowaniem domyślnych zakresów.
źródło
Możesz użyć metody wyszukiwania ActiveRecord, aby pobrać obiekty i je również posortować.
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
źródło
A jeśli chcesz przekazać dodatkowe argumenty, takie jak
dependent: :destroy
lub cokolwiek innego, powinieneś dołączyć je po lambdzie, na przykład:źródło