Ruby on Rails: bagaimana cara mengurutkan dengan dua kolom menggunakan ActiveRecord?

94

Saya ingin mengurutkan menurut dua kolom, satu adalah DateTime ( updated_at), dan yang lainnya adalah Desimal (Harga)

Saya ingin dapat mengurutkan terlebih dahulu berdasarkan update_at, lalu, jika beberapa item terjadi pada hari yang sama, urutkan berdasarkan Harga.

NullVoxPopuli
sumber

Jawaban:

66

Dengan asumsi Anda menggunakan MySQL,

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

Perhatikan perbedaan dari jawaban lainnya. The updated_atkolom akan menjadi timestamp penuh, jadi jika Anda ingin semacam berdasarkan hari itu diperbarui, Anda perlu menggunakan fungsi untuk mendapatkan hanya bagian tanggal dari timestamp. Di MySQL, itu DATE().

Daniel Vandersluis
sumber
7
Untuk berhenti bergabung dari pemutusan secara acak dengan pesan "kolom ambigu", Anda harus menggunakan versi yang lebih kuat berikut: :order => ["DATE(#{table_name}.updated_at)", :price](Perhatikan bahwa itu :priceadalah simbol.)
Jo Liss
Saya harus keluar dari kolom pesanan saya dengan orderseperti ini:Model.all(:order => "day asc, `order` asc")
mengabulkan
149

Di Rails 4 Anda dapat melakukan sesuatu yang mirip dengan:

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

foodan baradalah kolom di db.

Christian Fazzini
sumber
1
Rel 4 adalah yang terbesar.
Darth Egregious
57
Thing.find(:all, :order => "updated_at desc, price asc")

akan melakukan triknya.

Memperbarui:

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

adalah cara untuk pergi ke Rails 3. (Terima kasih @purs )

Erik Escobedo
sumber
4
Terima kasih @Erik - Saya tahu jawaban ini sudah lama jadi inilah peringatan saya bagi mereka yang melihatnya sekarang: Metode ini sudah tidak digunakan lagi mulai Rails 3.2. Gunakan Thing.all sebagai gantinya =)
Abdo
Benar, ini bekerja dengan baik untuk saya: Thing.all.order("updated_at DESC, price ASC")
cpursley
1
Pembaruan Anda sangat membantu bagi saya ketika saya perlu huruf kecil nilai-nilai diurutkan: Thing.order("LOWER(name), number").
Nick
36

Antarmuka Kueri Rekaman Aktif memungkinkan Anda menentukan atribut sebanyak yang Anda inginkan untuk mengurutkan kueri Anda:

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

atau jika Anda ingin lebih spesifik (terima kasih @ zw963 ):

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

Bonus: Setelah kueri pertama, Anda dapat merangkai kueri lain:

models = models.where('date >= :date', date: Time.current.to_date)
golfadas
sumber
Saya tahu ini adalah pos tua, tapi saya pribadi akan berubah modelke modelssehingga seseorang akan tahu itu pluralized. Hanya sebuah saran.
Tass
1
Saya pikir harus mengedit contoh yang lebih khusus: eg models = Model.order ({price:: desc}, {date:: desc}, {price: asc})
zw963
jika ada yang menempel ini dan melihat kesalahan metode tidak ditentukan, ada kesalahan ketik kecil di sini. Seharusnya :ascbukan asc:Model.order({price: :desc}, {date: :desc}, {price: :asc})
nayiaw
18

Sebenarnya ada banyak cara untuk melakukannya dengan menggunakan Active Record. Salah satu yang belum disebutkan di atas akan menjadi (dalam berbagai format, semuanya valid):

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

Mungkin lebih bertele-tele, tetapi secara pribadi saya merasa lebih mudah untuk mengaturnya. SQL diproduksi hanya dalam satu langkah:

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

Jadi, untuk pertanyaan awal:

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

Anda tidak perlu mendeklarasikan tipe data, ActiveRecord melakukannya dengan lancar, begitu juga DB Engine Anda

Ruby Racer
sumber
Ini berfungsi dengan baik saat menggunakan dua kolom dari dua tabel berbeda seperti: Member.includes (: voter) .order ("town_club asc"). Order ("voters.last_name asc")
bkunzi01
1
Apakah SQL yang Anda posting sesuai Model.order(foo: :asc).order(:bar => :desc).order(:etc)? Urutan klausa urutan dalam SQL adalah kebalikan dari apa yang saya dapatkan saat menjalankannya .to_sql.
Qaz
1
@Az ini sudah lama sekali. Saya pikir saya mungkin perlu memperbaiki yang ini, saya tidak pernah menyadarinya. Saya akan periksa lagi nanti. Terima kasih.
Ruby Racer
2
Model.all(:order => 'updated_at, price')
robertokl
sumber
0

Tak satu pun dari ini berhasil untuk saya! Setelah tepat 2 hari mencari dari atas dan bawah melalui internet, saya menemukan solusi !!

katakanlah Anda memiliki banyak kolom di tabel produk termasuk: special_price dan msrp. Ini adalah dua kolom yang kami coba sortir.

Oke, Pertama di Model Anda tambahkan baris ini:

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

Kedua, di Product Controller, tambahkan di mana Anda perlu melakukan pencarian:

@search = Product.sorted_by_special_price_asc_msrp_asc.search(search_params)
Max Alexander Hanna
sumber