1. ホーム
  2. ruby-on-rails

Rails アクティブレコード find(:all, :order => ) 問題

2023-09-30 13:11:11

質問

ActiveRecord::Base.findのオプション :order で一度に複数の列を検索することができないようなのですが、どうしたらよいでしょうか?

例えば、私は日付と出席カラムを持つ"Show"モデルを持っています。

以下のコードを実行すると

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

以下のような結果が得られます。

[#<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>]

以下のコードを実行すると

@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>]

でも、実行すると

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

または

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

または

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

日付で並べ替えるだけと同じ結果になります。

 [#<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>]

として、このような結果を得たいところです。

[#<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>]

これはログから生成されるクエリです。

[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

最後に、私のモデルを紹介します。

  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

何が足りないのだろう? 私は何を間違えているのか?

UPDATE: すべてのあなたの助けに感謝します、しかし、あなた方すべてが私と同じようにこまっていたようです。 問題を解決したのは、実際にデータベースを切り替えたことです。 私はデフォルトの sqlite3 から mysql に切り替えました。

どのように解決したのか?

私は、あなたの最初の例では、単純な :order => "日付" レコード 7 はレコードの前にソートされます 1 . この順序は、出席でソートするかどうかに関係なく、複数列のソートで結果を見る方法でもあります。

これは、もし日付がまったく同じでなければ、意味があるように思われます。 7 の日付が 1 . を見つける代わりに 日付 が正確に等しいことを発見して で並べ替え でソートされますが、クエリは日付が等しくないことを発見し、他のすべてのレコードのように単にそれでソートします。

SQLiteはDATEまたはDATETIMEデータ型のネイティブな理解を持っておらず、代わりに浮動小数点数またはユーザーが自分で解析しなければならないテキストの選択肢を与えていることを、私はブラウジングから知りました。データベース内の日付のリテラル表現が正確に等しくないということはあり得ますか?ほとんどの人は 日付関数を使用する を使用する必要があるようです。おそらく、order by カラムを 日付関数 のような具体的な比較対象を与えるような方法があるかもしれません。 日付(date) ASC, 出席 DESC . この構文がうまくいくかどうかはわかりませんが、あなたの問題を解決するために見ておくべき分野です。お役に立てれば幸いです。