Rails Active Record tìm vấn đề (: all,: order =>)


76

Tôi dường như không thể sử dụng tùy chọn ActiveRecord :: Base.find: đặt hàng cho nhiều cột cùng một lúc.

Ví dụ: tôi có mô hình "Hiển thị" với các cột ngày và ngày tham dự.

Nếu tôi chạy mã sau:

@shows = Show.find(:all, :order => "date")

Tôi nhận được các kết quả sau:

[#<Show id: 7, date: "2009-04-18", attending: 2>, 
 #<Show id: 1, date: "2009-04-18", attending: 78>, 
 #<Show id: 2, date: "2009-04-19", attending: 91>, 
 #<Show id: 3, date: "2009-04-20", attending: 16>,
 #<Show id: 4, date: "2009-04-21", attending: 136>]

Nếu tôi chạy mã sau:

@shows = Show.find(:all, :order => "attending DESC")

[#<Show id: 4, date: "2009-04-21", attending: 136>,
 #<Show id: 2, date: "2009-04-19", attending: 91>,
 #<Show id: 1, date: "2009-04-18", attending: 78>,
 #<Show id: 3, date: "2009-04-20", attending: 16>,
 #<Show id: 7, date: "2009-04-18", attending: 2>]

Nhưng, nếu tôi chạy:

@shows = Show.find(:all, :order => "date, attending DESC")

HOẶC LÀ

@shows = Show.find(:all, :order => "date, attending ASC")

HOẶC LÀ

@shows = Show.find(:all, :order => "date ASC, attending DESC")

Tôi nhận được kết quả giống như chỉ sắp xếp theo ngày:

 [#<Show id: 7, date: "2009-04-18", attending: 2>, 
 #<Show id: 1, date: "2009-04-18", attending: 78>, 
 #<Show id: 2, date: "2009-04-19", attending: 91>, 
 #<Show id: 3, date: "2009-04-20", attending: 16>,
 #<Show id: 4, date: "2009-04-21", attending: 136>]

Tôi muốn nhận được những kết quả sau:

[#<Show id: 1, date: "2009-04-18", attending: 78>,
#<Show id: 7, date: "2009-04-18", attending: 2>, 
 #<Show id: 2, date: "2009-04-19", attending: 91>, 
 #<Show id: 3, date: "2009-04-20", attending: 16>,
 #<Show id: 4, date: "2009-04-21", attending: 136>]

Đây là truy vấn được tạo từ nhật ký:

[4;35;1mUser Load (0.6ms)[0m   [0mSELECT * FROM "users" WHERE ("users"."id" = 1) LIMIT 1[0m
[4;36;1mShow Load (3.0ms)[0m   [0;1mSELECT * FROM "shows" ORDER BY date ASC, attending DESC[0m
[4;35;1mUser Load (0.6ms)[0m   [0mSELECT * FROM "users" WHERE ("users"."id" = 1) [0m

Cuối cùng, đây là mô hình của tôi:

  create_table "shows", :force => true do |t|
    t.string   "headliner"
    t.string   "openers"
    t.string   "venue"
    t.date     "date"
    t.text     "description"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.decimal  "price"
    t.time     "showtime"
    t.integer  "attending",   :default => 0
    t.string   "time"
  end

Tôi đang thiếu gì? Tôi đang làm gì sai?

CẬP NHẬT: Cảm ơn sự giúp đỡ của tất cả các bạn, nhưng có vẻ như tất cả các bạn đều gặp khó khăn như tôi. Những gì đã giải quyết vấn đề thực sự là chuyển đổi cơ sở dữ liệu. Tôi đã chuyển từ sqlite3 mặc định sang mysql.


Tôi không có thiết lập đường ray vào lúc này để kiểm tra mã của bạn; Truy vấn nào đang được tạo cho hai lệnh? Bạn sẽ có thể kiểm tra nhật ký / nhật ký để xem.
YênThứ nhất

Truy vấn thực sự sẽ rất hữu ích
aivarsak

Có thể không liên quan, nhưng bạn đang sử dụng phiên bản AR nào và DB nào?
Mike Woodhouse

[4; 35; 1m Tải của người dùng (0,6ms) [0m [0mSELECT * TỪ "người dùng" WHERE ("người dùng". "Id" = 1) GIỚI HẠN 1 [0m [4; 36; 1mShiển thị (3,0ms) [0m [ 0; 1mSELECT * FROM "hiển thị" ĐẶT HÀNG THEO ngày ASC, tham dự DESC [0m [4; 35; 1mUser Load (0,6ms) [0m [0mSELECT * FROM "users" WHERE ("users". "Id" = 1) [ 0 phút
CodingWithoutComments

Tôi đang sử dụng sqllite3 và đường ray phiên bản 2.2.2
CodingWithoutComments

Câu trả lời:


35

Tôi nhận thấy rằng trong ví dụ đầu tiên của bạn, đơn giản : order => "date" , bản ghi 7 được sắp xếp trước bản ghi 1 . Thứ tự này cũng là cách bạn xem kết quả trong sắp xếp nhiều cột, bất kể bạn có sắp xếp theo tham dự hay không.

Điều này dường như có ý nghĩa đối với tôi nếu các ngày không hoàn toàn giống nhau và ngày cho 7 là trước ngày cho 1 . Thay vì nhận thấy rằng các ngày là chính xác bằng nhau thì tiến hành sắp xếp theo cách tham dự , truy vấn phát hiện rằng các ngày không bằng nhau và chỉ cần sắp xếp theo như tất cả các bản ghi khác.

Tôi thấy khi duyệt xung quanh rằng SQLite không có hiểu biết nguyên bản về các kiểu dữ liệu DATE hoặc DATETIME và thay vào đó cung cấp cho người dùng lựa chọn số dấu phẩy động hoặc văn bản mà họ phải tự phân tích cú pháp. Có thể là sự thể hiện theo nghĩa đen của ngày tháng trong cơ sở dữ liệu không chính xác bằng nhau? Hầu hết mọi người dường như cần sử dụng các hàm ngày tháng để ngày tháng hoạt động như bạn mong đợi. Có lẽ có một cách để gói đơn hàng của bạn theo cột với một hàm ngày tháng sẽ cung cấp cho bạn một cái gì đó cụ thể để so sánh, chẳng hạn như ngày tháng (date) ASC, tham dự DESC . Tôi không chắc cú pháp đó hoạt động, nhưng đó là một lĩnh vực cần xem xét để giải quyết vấn đề của bạn. Hy vọng rằng sẽ giúp.


Điều đó có ý nghĩa - cột NGÀY thực sự có thể là DATETIME hoặc một số phần nhỏ khác - vì vậy bạn phải sắp xếp theo các phần ngày ... Ừ ... Tốt lắm
Matt Rogish

4
tôi đã chuyển cơ sở dữ liệu từ sqlite3 sang mysql. Điều này làm cho vấn đề biến mất.
CodingWithoutComments

46

Có thể là hai điều. Đầu tiên,

Mã này không được dùng nữa:

Model.find(:all, :order => ...)

nên là:

Model.order(...).all

Tìm không còn được hỗ trợ với: tất cả,: đặt hàng và nhiều tùy chọn khác.

Thứ hai, bạn có thể có một default_scope đã được thực thi một số đặt hàng trước khi bạn gọi findtrên Show.

Hàng giờ tìm hiểu trên internet đã dẫn tôi đến một số bài viết hữu ích giải thích vấn đề:


1
Model.all (: trật tự => ...) là tốt
mdpatrick

Model.order(...)tốt hơn
Yule

Trong rails 4.1 Model.all (: order => "field_name ASC") đưa ra lỗi sai số đối số (1 đối với 0). Model.order ("field_name ASC") thì không. Tìm thấy điều này trong khi nâng cấp một ứng dụng cũ.
Mark Davies

14

Vấn đề là ngày đó là một từ khóa sqlite3 dành riêng . Tôi đã gặp vấn đề tương tự với thời gian , cũng là một từ khóa dành riêng, hoạt động tốt trong PostgreSQL, nhưng không hoạt động trong sqlite3. Giải pháp là đổi tên cột .

Xem phần này: Sqlite3 activerecord: order => "time DESC" không sắp xếp


4

Tôi vừa gặp phải vấn đề tương tự, nhưng tôi quản lý để truy vấn của mình hoạt động trong SQLite như sau:

@shows = Show.order("datetime(date) ASC, attending DESC")

Tôi hy vọng điều này có thể giúp ai đó tiết kiệm thời gian


3

không phải nó chỉ :order => 'column1 ASC, column2 DESC'?


vâng, xin lỗi - cảm ơn vì đã chỉ ra điều đó. Đó là những gì tôi đã làm. Đã sửa trong câu hỏi.
CodingWithoutComments

điều này không hoạt động vì một số lý do. Tôi đã thử cái này. Bất kỳ ý tưởng khác?
CodingWithoutComments

3

Đảm bảo kiểm tra lược đồ trực tiếp ở cấp cơ sở dữ liệu. Tôi đã bị đốt cháy bởi điều này trước đây, ví dụ: trong đó, một quá trình di chuyển ban đầu được viết để tạo cột: datetime và tôi chạy nó cục bộ, sau đó điều chỉnh việc di chuyển thành một: date trước khi thực sự triển khai. Vì vậy, cơ sở dữ liệu của mọi người trông tốt, ngoại trừ của tôi, và các lỗi rất nhỏ.


2

Tôi hiểu tại sao các nhà phát triển Rails đã sử dụng sqlite3 để triển khai ngay lập tức, nhưng MySQL thực tế hơn rất nhiều, IMHO. Tôi nhận ra rằng nó phụ thuộc vào những gì bạn đang xây dựng ứng dụng Rails của mình, nhưng hầu hết mọi người sẽ chuyển tệp database.yml mặc định từ sqlite3 sang MySQL.

Rất vui vì bạn đã giải quyết được vấn đề của mình.


không thể đồng ý hơn. Phát triển với cùng một DB mà bạn sẽ triển khai. Nó sẽ giúp bạn tiết kiệm rất nhiều đau đầu trong thời gian dài.
đàn ông

2

Thật tốt là bạn đã tìm ra giải pháp của mình. Nhưng đó là một vấn đề thú vị. Tôi đã tự mình thử trực tiếp với sqlite3 (không qua đường ray) và không nhận được kết quả tương tự, đối với tôi, đơn đặt hàng đã ra như mong đợi.

Những gì tôi khuyên bạn nên làm nếu bạn muốn tiếp tục tìm hiểu vấn đề này là khởi động ứng dụng dòng lệnh sqlite3 và kiểm tra lược đồ và các truy vấn ở đó:

Điều này cho bạn thấy lược đồ: .schema

Và sau đó chỉ cần chạy câu lệnh select khi nó hiển thị trong các tệp nhật ký: SELECT * FROM "shows" ORDER BY date ASC, attending DESC

Bằng cách đó, bạn sẽ thấy nếu:

  1. Lược đồ trông như bạn muốn (ví dụ: ngày đó thực sự là một ngày)
  2. Rằng cột ngày thực sự chứa ngày chứ không phải dấu thời gian (nghĩa là bạn không có thời gian trong ngày làm rối loại sắp xếp)

1

Tôi đang sử dụng rails 6 và Model.all (: order 'columnName DESC') không hoạt động. Tôi đã tìm thấy câu trả lời chính xác trong OrderInRails

Điều này rất đơn giản.

@variable=Model.order('columnName DESC')

0

Điều này cũng có thể giúp:

Post.order(created_at: :desc)
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.