Ruby on Rails: як сортувати за двома стовпцями за допомогою ActiveRecord?


91

Я хочу сортувати за двома стовпцями, один - DateTime ( updated_at), а інший - десятковий (Ціна)

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

Відповіді:


64

Припускаючи, що ви використовуєте MySQL,

Model.all(:order => 'DATE(updated_at), price')

Зверніть увагу на відмінність від інших відповідей. updated_atКолонка буде повна мітка часу, так що якщо ви хочете сортувати на основі день вона була оновлена, вам потрібно використовувати функцію , щоб отримати тільки частина дати з позначки часу. У MySQL, тобто DATE().


7
Щоб зупинити випадкові розриви об'єднань із повідомленнями "неоднозначного стовпця", слід використовувати таку більш надійну версію: :order => ["DATE(#{table_name}.updated_at)", :price](Зверніть увагу, що :priceце символ.)
Джо Лісс,

Я повинен був уникнути мого колонці замовлення з orderось так:Model.all(:order => "day asc, `order` asc")
грантом


56
Thing.find(:all, :order => "updated_at desc, price asc")

зробить трюк.

Оновлення:

Thing.all.order("updated_at DESC, price ASC")

це шлях Rails 3. (Дякую @cpursley )


4
Дякую @Erik - Я знаю, що ця відповідь стара, тому ось моє попередження для тих, хто її бачить зараз: Цей метод застарілий, починаючи з Rails 3.2. Замість цього використовуйте Thing.all =)
Абдо

Правильно, це добре в мене Thing.all.order("updated_at DESC, price ASC")
вийшло

1
Ваше оновлення було корисно для мене , коли я потребував нижній регістр відсортованих значень: Thing.order("LOWER(name), number").
Нік

36

Інтерфейс запиту активних записів дозволяє вказати стільки атрибутів, скільки потрібно для упорядкування запиту:

models = Model.order(:date, :hour, price: :desc)

або якщо ви хочете отримати більш конкретну інформацію (спасибі @ zw963 ):

models = Model.order(price: :desc, date: :desc, price: :asc) 

Бонус: Після першого запиту ви можете зв’язати інші запити:

models = models.where('date >= :date', date: Time.current.to_date)

Я знаю, що це стара публікація, але я особисто змінив modelби її, modelsщоб людина знала, що вона плюралізована. Просто пропозиція.
Тасс

1
Я думаю, слід відредагувати більш спеціальний приклад: наприклад, models = Model.order ({price:: desc}, {date:: desc}, {price: asc})
zw963,

якщо хтось вставив це і побачив невизначену помилку методу, тут є невелика помилка. Це має бути :ascзамість asc:Model.order({price: :desc}, {date: :desc}, {price: :asc})
nayiaw

18

Насправді існує багато способів зробити це за допомогою Active Record. Той, про який не згадувалося вище, буде (у різних форматах, усі дійсні):

Model.order(foo: :asc).order(:bar => :desc).order(:etc)

Можливо, це більш багатослівно, але особисто мені легше керувати. SQL створюється лише за один крок:

SELECT "models".* FROM "models" ORDER BY "models"."etc" ASC, "models"."bar" DESC, "models"."foo" ASC

Таким чином, для вихідного питання:

Model.order(:updated_at).order(:price)

Вам не потрібно оголошувати тип даних, ActiveRecord робить це гладко, як і ваш механізм DB


Це чудово працює при використанні двох стовпців з двох різних таблиць, таких як: Member.includes (: voter) .order ("town_club asc"). Order ("избиратели.last_name asc")
bkunzi01

1
Чи відповідає розміщений вами SQL Model.order(foo: :asc).order(:bar => :desc).order(:etc)? Порядок пропозицій про порядок в SQL протилежний тому, що я отримую, коли я працюю .to_sqlна цьому.
Каз,

1
@Qaz це давно. Думаю, мені, мабуть, потрібно виправити цю, я ніколи не помічав. Я ще раз перевірю пізніше. Дякую.
Ruby Racer


0

Жодне з цього не працювало для мене! Після рівно 2 днів перегляду зверху та знизу через Інтернет я знайшов рішення !!

припустимо, у вас є багато стовпців у таблиці товарів, включаючи: special_price та msrp. Це два стовпці, з якими ми намагаємося сортувати.

Добре, спочатку у своїй моделі додайте цей рядок:

named_scope :sorted_by_special_price_asc_msrp_asc, { :order => 'special_price asc,msrp asc' }

По-друге, у Контролері продукту додайте, де потрібно виконати пошук:

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