Ruby on Rails: Làm cách nào để sắp xếp với hai cột bằng ActiveRecord?


91

Tôi muốn sắp xếp theo hai cột, một là DateTime ( updated_at) và cột kia là Decimal (Giá)

Tôi muốn có thể sắp xếp trước tiên theo updated_at, sau đó, nếu nhiều mặt hàng xảy ra trong cùng một ngày, hãy sắp xếp theo Giá.

Câu trả lời:


64

Giả sử bạn đang sử dụng MySQL,

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

Lưu ý sự khác biệt với các câu trả lời khác. Các updated_atcột sẽ là một dấu thời gian đầy đủ, vì vậy nếu bạn muốn loại dựa trên ngày nó đã được cập nhật, bạn cần phải sử dụng một chức năng để có được chỉ là một phần ngày từ dấu thời gian. Trong MySQL, đó là DATE().


7
Để ngừng tham gia từ phá vỡ một cách ngẫu nhiên với những thông điệp "cột mơ hồ", bạn nên sử dụng phiên bản mạnh mẽ hơn sau: :order => ["DATE(#{table_name}.updated_at)", :price](Lưu ý rằng :pricelà một biểu tượng.)
Jo Liss

Tôi phải thoát khỏi cột đơn hàng của tôi với ordernhư vậy:Model.all(:order => "day asc, `order` asc")
cấp

147

Trong Rails 4, bạn có thể làm điều gì đó tương tự như:

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

foobarlà các cột trong db.


1
Rails 4 là lớn nhất.
Darth Egrerious

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

sẽ thực hiện thủ thuật.

Cập nhật:

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

là cách để đi Rails 3. (Cảm ơn @cpursley )


4
Cảm ơn bạn @Erik - Tôi biết câu trả lời này đã cũ nên đây là cảnh báo của tôi cho những người đang nhìn thấy nó bây giờ: Phương pháp này đã không được chấp nhận khi bắt đầu Rails 3.2. Sử dụng Thing.all thay vì =)
Abdo

Đúng, điều này làm việc tốt cho tôi: Thing.all.order("updated_at DESC, price ASC")
cpursley

1
Cập nhật của bạn là hữu ích cho tôi khi tôi cần thiết để thành chữ thường các giá trị được sắp xếp: Thing.order("LOWER(name), number").
Nick

36

Giao diện Truy vấn Bản ghi Hoạt động cho phép bạn chỉ định bao nhiêu thuộc tính bạn muốn để sắp xếp truy vấn của mình:

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

hoặc nếu bạn muốn biết cụ thể hơn (cảm ơn @ zw963 ):

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

Phần thưởng: Sau truy vấn đầu tiên, bạn có thể xâu chuỗi các truy vấn khác:

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

Tôi biết đây là một bài đăng cũ, nhưng cá nhân tôi muốn thay đổi modelthành modelsđể mọi người biết nó đa dạng. Chỉ là một gợi ý.
Tass

1
Tôi nghĩ nên chỉnh sửa một ví dụ đặc biệt hơn: ví dụ: models = Model.order ({price:: desc}, {date:: desc}, {price: asc})
zw963

nếu ai đó đã dán cái này và thấy lỗi phương thức không xác định, có một lỗi đánh máy nhỏ ở đây. Nó nên được :ascthay vì asc:Model.order({price: :desc}, {date: :desc}, {price: :asc})
nayiaw

18

Trên thực tế có nhiều cách để làm điều đó bằng Active Record. Một cái chưa được đề cập ở trên sẽ là (ở nhiều định dạng khác nhau, tất cả đều hợp lệ):

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

Có lẽ nó dài dòng hơn, nhưng cá nhân tôi thấy nó dễ quản lý hơn. SQL chỉ được sản xuất trong một bước:

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

Do đó, đối với câu hỏi ban đầu:

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

Bạn không cần phải khai báo kiểu dữ liệu, ActiveRecord thực hiện điều này một cách suôn sẻ và DB Engine của bạn cũng vậy


Đây hoạt động tuyệt vời khi sử dụng hai cột từ hai bảng khác nhau như: Member.includes (: cử tri) .order ( "town_club asc") theo thứ tự ( "voters.last_name asc").
bkunzi01

1
SQL bạn đã đăng tương ứng với Model.order(foo: :asc).order(:bar => :desc).order(:etc)? Thứ tự của các mệnh đề thứ tự trong SQL trái ngược với những gì tôi nhận được khi chạy .to_sqltrên đó.
Qaz

1
@Qaz cái này lâu rồi. Tôi nghĩ tôi có lẽ cần phải sửa lại điều này, tôi chưa bao giờ để ý. Tôi sẽ kiểm tra lại sau. Cảm ơn.
Ruby Racer


0

Không ai trong số này làm việc cho tôi! Sau đúng 2 ngày tìm kiếm trên mạng, tôi đã tìm ra giải pháp !!

giả sử bạn có nhiều cột trong bảng sản phẩm bao gồm: giá_phí_đặc_nghiệp và giá_mạch. Đây là hai cột mà chúng tôi đang cố gắng sắp xếp.

Được rồi, Đầu tiên trong Mô hình của bạn, hãy thêm dòng này:

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

Thứ hai, trong Bộ điều khiển sản phẩm, hãy thêm nơi bạn cần thực hiện tìm kiếm:

@search = Product.sorted_by_special_price_asc_msrp_asc.search(search_params)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.