Ruby on Rails: ActiveRecord kullanarak iki sütunla nasıl sıralayabilirim?


94

İki sütuna göre sıralamak istiyorum, biri DateTime ( updated_at) ve diğeri Decimal (Fiyat)

Önce updated_at'a göre sıralayabilmek, ardından aynı gün birden fazla öğe ortaya çıkarsa, Fiyata göre sıralayabilmek istiyorum.

Yanıtlar:


66

MySQL kullandığınızı varsayarsak,

Model.all(:order => 'DATE(updated_at), price')

Diğer cevaplardan ayrıma dikkat edin. updated_atSütun sıralama dayalı istiyorum eğer öyleyse, tam bir zaman damgası olacaktır gün o güncellendi, sen damgası sadece tarih bölümünü almak için bir işlevi kullanmak gerekir. MySQL'de yani DATE().


7
Dur rastgele "belirsiz sütun" mesajları ile kırma katılır için aşağıdaki daha sağlam sürümünü kullanmalıdır: :order => ["DATE(#{table_name}.updated_at)", :price](Not :pricebir semboldür.)
Jo Liss

Ben ile benim sipariş sütun kaçmak zorunda order: gibi pekModel.all(:order => "day asc, `order` asc")
hibe

149

Rails 4'te aşağıdakilere benzer bir şey yapabilirsiniz:

Model.order(foo: :asc, bar: :desc)

foove bardb'deki sütunlardır.


1
Raylar 4 en iyisidir.
Darth Aleni

57
Thing.find(:all, :order => "updated_at desc, price asc")

hile yapacak.

Güncelleme:

Thing.all.order("updated_at DESC, price ASC")

Rails 3 yoludur. (Teşekkürler @cpursley )


4
Teşekkür ederim @Erik - Bu cevabın eski olduğunu biliyorum, bu yüzden şimdi görenler için uyarım: Bu yöntem Rails 3.2'den itibaren kullanımdan kaldırıldı. Bunun yerine Thing.all kullanın =)
Abdo

Doğru, bu benim için iyi çalıştı: Thing.all.order("updated_at DESC, price ASC")
cpursley

1
Ben sıralanmış değerlerini küçük harfe gerektiğinde Güncellemeniz benim için yararlı oldu: Thing.order("LOWER(name), number").
Nick

36

Aktif Kayıt Sorgu Arayüzü , sorgunuzu sıralamak istediğiniz kadar öznitelik belirtmenize izin verir :

models = Model.order(:date, :hour, price: :desc)

veya daha spesifik olmak istiyorsanız (teşekkürler @ zw963 ):

models = Model.order(price: :desc, date: :desc, price: :asc) 

Bonus: İlk sorgudan sonra, diğer sorguları zincirleyebilirsiniz:

models = models.where('date >= :date', date: Time.current.to_date)

Bunun eski bir gönderi olduğunu biliyorum, ancak şahsen değiştirdim model, modelsböylece bir kişi çoğul olduğunu bilsin. Sadece bir öneri.
Tass

1
Sanırım daha özel bir örnek düzenlemeliyim: ör. Modeller = Model.order ({fiyat:: azalan}, {tarih:: azalan}, {fiyat: artan})
zw963

Herhangi biri bunu yapıştırdıysa ve tanımsız yöntem hatası gördüyse, burada küçük bir yazım hatası var. Bunun :ascyerine şu şekilde olmalıdır asc:Model.order({price: :desc}, {date: :desc}, {price: :asc})
nayiaw

18

Aslında bunu Active Record kullanarak yapmanın birçok yolu vardır. Yukarıda bahsedilmeyen bir tanesi (çeşitli formatlarda, tümü geçerli) olacaktır:

Model.order(foo: :asc).order(:bar => :desc).order(:etc)

Belki daha ayrıntılı, ama kişisel olarak yönetmeyi daha kolay buluyorum. SQL yalnızca tek adımda üretilir:

SELECT "models".* FROM "models" ORDER BY "models"."etc" ASC, "models"."bar" DESC, "models"."foo" ASC

Dolayısıyla, orijinal soru için:

Model.order(:updated_at).order(:price)

Veri türünü bildirmenize gerek yoktur, ActiveRecord bunu sorunsuz bir şekilde yapar ve DB Motorunuz


Bu, aşağıdaki gibi iki farklı tablodan iki sütun kullanırken harika çalışıyor: Member.includes (: voter) .order ("town_club asc"). Order ("voters.last_name asc")
bkunzi01

1
Gönderdiğiniz SQL karşılık geliyor Model.order(foo: :asc).order(:bar => :desc).order(:etc)mu? SQL'deki sipariş cümlelerinin sırası, bunun .to_sqlüzerinde çalıştırdığım zaman aldığımın tam tersi .
Qaz

1
@Qaz bu uzun zaman önce. Sanırım bunu muhtemelen düzeltmem gerekiyor, hiç fark etmemiştim. Daha sonra tekrar kontrol edeceğim. Teşekkürler.
Yakut Racer


0

Bunların hiçbiri benim için işe yaramadı! İnternette tam olarak 2 gün aşağıya baktıktan sonra bir çözüm buldum !!

Diyelim ki ürünler tablosunda özel_fiyat ve msrp dahil birçok sütununuz var. Bunlar, sıralamaya çalıştığımız iki sütun.

Tamam, İlk olarak Modelinize şu satırı ekleyin:

named_scope :sorted_by_special_price_asc_msrp_asc, { :order => 'special_price asc,msrp asc' }

İkinci olarak, Ürün Denetleyicisinde, aramayı yapmanız gereken yeri ekleyin:

@search = Product.sorted_by_special_price_asc_msrp_asc.search(search_params)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.