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)