Rails Active Record find (: all,: order =>) issue

Кажется, я не могу использовать параметр ActiveRecord:: Base.find: заказывайте более одного столбца за раз.

Например, у меня есть модель "Показать" с датой и посещением столбцов.

Если я запустил следующий код:

@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

Что мне не хватает? Что я делаю неправильно?

ОБНОВЛЕНИЕ: Спасибо за вашу помощь, но кажется, что вы все были в тупике, насколько я был. То, что решило проблему, было фактически переключением баз данных. Я переключился с SQL3 по умолчанию на mysql.

Ответ 1

Я заметил, что в первом примере простая : order = > "дата" , запись 7 сортируется перед записью 1. Этот порядок также показывает, как вы видите результаты в сортировке нескольких столбцов, независимо от того, сортируете ли вы, посещая.

Мне кажется, это имеет смысл, если даты не совпадают, а дата 7 - до даты 1. Вместо того, чтобы находить, что дата s в точности равны, а затем сортировка по посещению, запрос обнаруживает, что даты не равны и просто сортируются таким образом, как и все остальные записи.

Я вижу, что SQLite не имеет собственного понимания типов данных DATE или DATETIME и вместо этого дает пользователям выбор чисел с плавающей запятой или текста, которые они должны анализировать самостоятельно. Возможно ли, что буквальное представление дат в базе данных не совсем одинаково? Большинство людей, похоже, нуждаются в использовании функций даты, так что даты ведут себя так, как вы ожидали. Возможно, есть способ обернуть ваш заказ по столбцу функцией date, которая даст вам что-то конкретное для сравнения, например date (date) ASC, посещая DESC. Я не уверен, что синтаксис работает, но это область для поиска решения вашей проблемы. Надеюсь, что это поможет.

Ответ 2

Может быть две вещи. Во-первых,

Этот код устарел:

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

должен быть:

Model.order(...).all

Поиск больше не поддерживается с помощью: all,: order и многих других опций.

Во-вторых,, возможно, у вас был параметр default_scope, который выполнял некоторый порядок, прежде чем вы вызвали find на Show.

Часы копания в Интернете привели меня к нескольким полезным статьям, которые объясняют проблему:

Ответ 3

Проблема заключается в том, что дата является зарезервированным ключевым словом sqlite3. У меня была аналогичная проблема со временем, а также зарезервированное ключевое слово, которое отлично работало в PostgreSQL, но не в sqlite3. Решение переименовывает столбец.

Смотрите это: Sqlite3 activerecord: order = > "время DESC" не сортирует

Ответ 4

Я просто столкнулся с той же проблемой, но мне удалось заставить мой запрос работать в SQLite следующим образом:

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

Надеюсь, это поможет кому-то сэкономить время

Ответ 5

это не только :order => 'column1 ASC, column2 DESC'?

Ответ 6

Обязательно проверьте схему на уровне базы данных напрямую. Я был сожжен этим раньше, где, например, миграция была первоначально написана для создания столбца: datetime, и я запустил его локально, а затем изменил переход на дату: до фактического развертывания. Таким образом, все базы данных выглядят хорошо, за исключением моих, а ошибки - тонкие.

Ответ 7

Я понимаю, почему разработчики Rails пошли с sqlite3 для готовой реализации, но MySQL гораздо более практичен, ИМХО. Я понимаю, что это зависит от того, для чего вы строите приложение Rails, но большинство людей собирается переключить файл database.yml по умолчанию из sqlite3 в MySQL.

Рад решить вашу проблему.

Ответ 8

Хорошо, что вы нашли свое решение. Но это интересная проблема. Я пробовал это непосредственно непосредственно с sqlite3 (не проходя через рельсы) и не получал тот же результат, для меня порядок вышел так, как ожидалось.

То, что я предлагаю вам сделать, если вы хотите продолжить копание в этой проблеме, - это запустить приложение командной строки sqlite3 и проверить схему и запросы там:

Это показывает вам схему: .schema

А затем просто запустите оператор select, как он появился в файлах журнала: SELECT * FROM "shows" ORDER BY date ASC, attending DESC

Таким образом вы видите, что:

  • Схема выглядит так, как вам хочется (эта дата на самом деле является датой, например)
  • То, что столбец даты фактически содержит дату, а не временную метку (т.е. что у вас нет времени суток, которое испортило сортировку)

Ответ 9

Это также может помочь:

Post.order(created_at: :desc)