Проблема пошуку активного запису Rails (: all,: order =>)


76

Здається, я не можу використовувати параметр 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

Чого мені не вистачає? Що я роблю не так?

ОНОВЛЕННЯ: Дякую за всю вашу допомогу, але, схоже, всі ви були тупими так само, як і я. Що вирішило проблему, насправді було переключення баз даних. Я перейшов із типового sqlite3 на mysql.


На даний момент у мене немає налаштувань рейок для перевірки вашого коду; Який запит створюється для двох команд? Ви повинні мати можливість перевірити журнали в / журналах, щоб побачити.
YenTheFirst

Запит був би дуже корисним
aivarsak

Можливо, це не має значення, але яку версію AR ви використовуєте та яку БД?
Майк Вудхаус,

[4; 35; 1мЗавантаження користувача (0,6 мс) [0м [0мВИБІР * З "користувачів" ДЕ ("користувачі". "Ід" = 1) ОБМЕЖЕННЯ 1 [0м [4; 36; 1мПоказати навантаження (3,0 мс] [0 м [ 0; 1мВИБІР * ВІД "показує" ЗАМОВИТИ ПО ДАТІ ASC, відвідуючи DESC [0м [4; 35; 1мВикористання користувача (0,6мс) [0м [0мВИБІР * ВІД "користувачів" ДЕ ("користувачі". "Id" = 1) [ 0м
CodingWithoutComments

Я використовую sqllite3 і rails версії 2.2.2
CodingWithoutComments

Відповіді:


35

Я помічаю, що у вашому першому прикладі просте : order => "date" , запис 7 сортується перед записом 1 . Цей порядок також визначає, як ви бачите результати сортування в кілька стовпців, незалежно від того, чи сортуєте ви за участю.

Здавалося б, це мало б сенс для мене, якби дати були не зовсім однаковими, а дата для 7 - до дати 1 . Замість того, щоб виявити, що дати точно однакові, а потім перейти до сортування за участю , запит виявляє, що дати не рівні, і просто сортує за цим, як і всі інші записи.

Переглядаючи, я бачу, що SQLite не має власного розуміння типів даних DATE або DATETIME, а натомість дає користувачам вибір чисел із плаваючою комою або тексту, які вони повинні проаналізувати самі. Чи можливо, що буквальне представлення дат у базі даних не зовсім рівне? Здається, більшості людей потрібно використовувати функції дати, щоб дати поводились так, як ви очікували. Можливо, є спосіб обернути ваше замовлення стовпчиком із функцією дати, яка дасть вам щось конкретне для порівняння, наприклад, дата (дата) ASC, відвідуючи DESC . Я не впевнений, що синтаксис працює, але це область, на яку слід звернути увагу для вирішення вашої проблеми. Сподіваюся, що це допомагає.


Це має сенс - стовпець DATE може насправді бути DATETIME або якоюсь іншою дробовою частиною - тож вам доведеться впорядковувати за датами ... Так ... Хороший улов
Matt Rogish

4
я переключив бази даних з sqlite3 на mysql. Це змусило проблему зникнути.
CodingWithoutComments

46

Можуть бути дві речі. Спочатку,

Цей код застарілий:

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

має бути:

Model.order(...).all

Пошук більше не підтримується параметрами: all,: order та багатьма іншими параметрами.

По-друге, можливо , у вас був default_scope, який виконував певне замовлення до того, як ви зателефонувалиfind на Show.

Години копання в Інтернеті привели мене до кількох корисних статей, які пояснюють проблему:


1
Model.all (: order => ...) добре
mdpatrick

Model.order(...)краще
Yule

У напрямках 4.1 Model.all (: order => "ім'я_поля ASC") видає неправильну кількість аргументів (1 для 0) помилка. Model.order ("ім'я_поля ASC") цього не робить. Знайшов це під час оновлення старої програми.
Mark Davies

14

Проблема в тому, що дата - це зарезервоване ключове слово sqlite3 . У мене була подібна проблема з часом , також зарезервоване ключове слово, яке чудово працювало в PostgreSQL, але не в sqlite3. Рішенням є перейменування стовпця .

Дивіться це: Sqlite3 activerecord: order => "час DESC" не сортується


4

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

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

Сподіваюся, це може допомогти комусь заощадити трохи часу



3

Не забудьте перевірити схему безпосередньо на рівні бази даних. Це мене вже спалило раніше, де, наприклад, спочатку було перенесено міграцію для створення стовпця: datetime, і я запустив її локально, а потім переправив міграцію на: date до фактичного розгортання. Таким чином, база даних усіх виглядає добре, крім моєї, а помилки витончені.


2

Я розумію, чому розробники Rails використовували sqlite3 для повної реалізації, але MySQL набагато практичніший, IMHO. Я усвідомлюю, що це залежить від того, для чого ви створюєте додаток Rails, але більшість людей збирається переключити стандартний файл database.yml із sqlite3 на MySQL.

Радий, що ви вирішили свою проблему.


не міг більше погодитись. Розробляйте з тією самою БД, яку ви збираєтесь розгортати. Це врятує вам стільки головного болю в довгостроковій перспективі.
brettish

2

Добре, що ви знайшли своє рішення. Але це цікава проблема. Я спробував це безпосередньо з sqlite3 (не проходячи через рейки) і не отримав такого самого результату, для мене замовлення вийшло, як очікувалося.

Що я пропоную вам зробити, якщо ви хочете продовжувати викопувати цю проблему, це запустити програму командного рядка sqlite3 та перевірити схему та запити там:

Це покаже вам схему: .schema

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

Таким чином ви бачите, чи:

  1. Схема виглядає так, як вам хочеться (ця дата фактично є датою, наприклад)
  2. Що стовпець дати насправді містить дату, а не позначку часу (тобто, що у вас немає часу доби, який зіпсує сортування)

1

Я використовую рейки 6, і Model.all (: order 'columnName DESC') не працює. Я знайшов правильну відповідь у OrderInRails

Це дуже просто.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.