Lai lịch:
Tôi có Product
mô hình bao gồm 4 loại
class Product < ActiveRecord::Base
enum category: [:recent, :cheapest, :most_expensive, :popular]
end
Tôi đã triển khai một tùy chỉnh ORDER BY
cho từng danh mục với phân trang ( LIMIT 10
), vì vậy khi tôi nhận được danh sách sản phẩm, tôi sẽ nhận được nhiều SQL
truy vấn với các truy vấn khác nhau ORDER BY
trong mỗi truy vấn như sau:
gần đây: SELECT "products".* FROM "products" ORDER BY "products"."created_at" DESC LIMIT 10
rẻ nhất:SELECT "products".* FROM "products" ORDER BY "products"."price" ASC LIMIT 10
đắt nhất: SELECT "products".* FROM "products" ORDER BY "products"."price" DESC LIMIT 10
phổ biến: SELECT "products".* FROM "products" ORDER BY "products"."popularity" DESC, "products"."created_at" DESC LIMIT 10
Vì vậy, như đã đề cập, mỗi truy vấn ở trên, kết quả a Product::ActiveRecord_Relation
chứa 10 sản phẩm với thứ tự khác nhau cho mỗi truy vấn.
Câu hỏi:
Tôi đã thêm cột mới vào Product
mô hình featured
có giá trị boolean và tôi cần áp dụng ORDER BY featured DESC
ở đầu mỗi truy vấn với việc giữ nguyên các ORDER BY
trường khác (nghĩa là truy vấn phổ biến phải như thế này SELECT "products".* FROM "products" ORDER BY "products"."featured" DESC, "products"."popularity" DESC, "products"."created_at" DESC LIMIT 10
).
Lưu ý: ORDER BY featured DESC
chỉ được thêm vào ở đầu ORDER BY
câu lệnh trước và nó được áp dụng trên tập hợp con không phải trên toàn bộ mô hình.
Những gì tôi đã thử?
Tôi đã thử các tình huống sau:
- Thêm
@products = @products.order(featured: :desc)
bộ điều khiển vào nhưng kết quả không như mong đợi vì nó thêm đơn hàng vào cuối đơn hàng hiện có theo chuỗi. - Sử dụng
default_scope
trong mô hình Sản phẩmdefault_scope { order(featured: :desc) }
nhưng kết quả không như mong đợi vì nó thực hiện đơn hàng trên toàn bộ mô hình, nhưng kết quả mong đợi là áp dụng thứ tự chỉ trên tập con (10 bản ghi). - sử dụng
reorder
trong bộ điều khiển@products = @products.reorder('').order(featured: :desc)
nhưng kết quả vẫn không như mong đợi vì điều này loại bỏ thứ tự cũ và thực sự tôi cần giữ nó nhưng ở cuốiORDER BY
chuỗi
Giải pháp duy nhất tôi có thể làm là sử dụng biến chuỗi để lưu thứ tự trước đó theo chuỗi, sau đó sử dụng reorder('').order(featured: :desc)
và cuối cùng nối chuỗi vào cuối new ORDER BY
:
current_order = @products.to_sql[@products.to_sql.downcase.index('order by')+8..@products.to_sql.downcase.index('limit')-1]
@products = @products.reorder("featured desc, #{current_order}" )
Nhưng tôi chắc rằng có một giải pháp tốt hơn mà tôi cần sự hỗ trợ của bạn để đạt được nó.
Bản tóm tắt:
Như tóm tắt trong các nhận xét bên dưới, tôi cần triển khai như sau:
Chỉ r
ở một nơi r = M.order(:a)
, tôi muốn chạy r.something(:b)
và nhận được hiệu quả M.order(:b).order(:a)
hơn là những M.order(:a).order(:b)
thứ r.order(:b)
sẽ mang lại cho bạn