2009-04-13 35 views
74

Tôi dường như không thể sử dụng tùy chọn ActiveRecord :: Base.find: đặt nhiều hơn một cột cùng một lúc.Rails Active Record tìm thấy (: all,: order =>) issue

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

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

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

tôi nhận được kết quả như 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 đoạn 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

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

HOẶC

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

tôi nhận được kết quả tương tự 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>] 

Trong trường hợp như, tôi muốn để có được những kết quả này:

[#<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à câu hỏi được tạo ra từ các bản ghi:

[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 thiếu gì? Tôi đang làm gì sai?

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

+0

Tôi không có một 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 có thể kiểm tra nhật ký trong/nhật ký để xem. – YenTheFirst

+0

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

+0

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

Trả lời

36

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

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

Tôi thấy việc duyệt xung quanh SQLite không có sự hiểu biết riêng về 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 chấm động hoặc văn bản mà họ phải phân tích cú pháp. Có thể là sự biểu diễn bằng chữ của các ngày trong cơ sở dữ liệu không chính xác bằng nhau không? Hầu hết mọi người dường như cần phải use date functions để những ngày đó hoạt động như bạn mong đợi. Có lẽ có một cách để bọc đơn đặt hàng của bạn theo cột với số date function sẽ cung cấp cho bạn thứ gì đó cụ thể để so sánh, như ngày ngày (ASC) 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.

+0

cảm ơn. bạn đã cho tôi một cái gì đó để suy nghĩ về. – CodingWithoutComments

+0

Điều đó có ý nghĩa - cột NGÀY thực sự có thể là DATETIME hoặc một số phần phân đoạn khác - vì vậy bạn phải đặt hàng theo các bộ phận ngày ... Yeah ... Tốt bắt –

+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

3

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

+0

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

+0

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

3

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

2

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

Rất vui khi bạn giải quyết được sự cố của mình.

+0

không thể đồng ý hơn. Phát triển với cùng một DB 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. – brettish

2

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

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

này cho bạn thấy sơ đồ: .schema

Và sau đó chỉ cần chạy các câu lệnh select vì nó xuất hiện trong các tập tin log: SELECT * FROM "shows" ORDER BY date ASC, attending DESC

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

  1. Giản đồ trông giống như bạn muốn (ví dụ ngày đó thực sự là ngày)
  2. Đó là 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 messes lên các loại)
14

vấn đề là ngày là một từ khóa reserved sqlite3. Tôi đã có một 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 đang đổi tên cột.

Xem này: Sqlite3 activerecord :order => "time DESC" doesn't sort

44

Có thể là hai điều.Thứ nhất,

Mã này bị phản đối:

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

nên là:

Model.order(...).all 

Find không còn được hỗ trợ với: tất cả,: trật tự, và nhiều lựa chọn khác.

Thứ hai, bạn có thể đã có default_scope thực thi một số yêu cầu trước khi bạn gọi find trên Show.

Giờ làm việc đào bới xung quanh trên internet dẫn tôi đến một vài điều hữu ích mà giải thích vấn đề này:

+1

Model.all (: order => ...) là tốt – mdpatrick

+0

'Model.order (...)' là tốt hơn – Yule

+0

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

4

Tôi chỉ chạy vào cùng một vấn đề, nhưng tôi quản lý để truy vấn của tôi 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 đỡ một ai đó tiết kiệm thời gian

0

này có thể giúp quá:

Post.order(created_at: :desc) 
Các vấn đề liên quan