Я пытаюсь упорядочить свои результаты по разным строковым выводам.

Итак, у меня есть 3 разных: заявляет, что может быть «билет», который пользователь устанавливает из формы.

  • открыто
  • Приостановлено
  • Закрыто

Когда я хочу вызвать ticket.all, я хочу иметь возможность отсортировать его в указанном выше порядке, чтобы он сгруппировал их по типу статуса.

Итак, как я могу сказать сначала отсортировать его по всем «Открытым», затем по «приостановленным», а затем по «закрытым» в одном списке?

  scope :statuses,  lambda { where(:status => "open", "paused",  "closed") }

Затем я вызываю ticket.statuses в своем контроллере билетов.

Я знаю, что лямбда-запрос "где" неверен, но я не знаю, как это сделать по-другому? Как бы вы сделали order_by на строках? Должен ли я вместо этого указывать числовые значения для: status?

Я использую MYSQL и драгоценный камень MYSQL2

0
paulkennethkent 14 Мар 2014 в 16:51
Скажите, пожалуйста, какую СУБД вы используете - mysql, sqlite, pgsql и т.д.
 – 
Max Williams
14 Мар 2014 в 16:56
Mysql, используя гем mysql2.
 – 
paulkennethkent
17 Мар 2014 в 14:38
Спасибо - этот код должен работать в mysql. Кстати, хорошо поместить эту информацию в ОП.
 – 
Max Williams
17 Мар 2014 в 16:13

3 ответа

Лучший ответ

Если вы все равно собираетесь получить все билеты, это будет проще сделать путем сортировки по рельсам. Например

tickets = Ticket.where(:some_condition => some_value)
tickets_by_status = []
['open', 'paused', 'closed'].each do |status|
  tickets_by_status.concat tickets.select{|ticket| ticket.status == status}
end

Вместо того, чтобы абстрагироваться с помощью области видимости, рассмотрите возможность создания метода класса в модели Ticket, например all_by_status.

[РЕДАКТИРОВАТЬ]

Если вам не нужно, чтобы билеты появлялись в указанном вами порядке, вы можете просто заказать их по статусу. Это будет отсортировано по статусу в алфавитном порядке (закрыто, открыто, приостановлено)

Ticket.order(:status)
1
Slicedpan 14 Мар 2014 в 17:51
Например, это несовместимо с нумерацией страниц, которую он может захотеть добавить в какой-то момент. Лучше сделать это в sql с самого начала, если это возможно.
 – 
Max Williams
14 Мар 2014 в 17:04

Здесь вам не нужна лямбда: вам нужно использовать лямбда в области видимости только тогда, когда одно из значений в ней может отличаться. Кроме того, я не думаю, что это запрос where, не так ли? Правильно ли я полагаю, что вы просто хотите заказать билеты по их стоимости status и не устанавливаете никаких условий?

Если это так, попробуйте следующее:

scope :statuses, order("field(status, 'open', 'paused', 'closed')")

Это специфично для MySQL. Для postgres вам нужно сделать оператор CASE, который намного более неуклюжий:

scope :statuses, order("CASE WHEN status='open' THEN 1 WHEN status='paused' THEN 2 WHEN status='closed' THEN 3 ELSE 4 END")

(я не тестировал вышеизложенное, но думаю, что это сработает).

1
Max Williams 14 Мар 2014 в 17:03
Вы хотите сказать, что он не отображает старые данные? Или что он делает? Вам нужно читать то, что вы печатаете... Не могли бы вы дать более подробную информацию, пожалуйста. Кэшируете ли вы какие-либо данные?
 – 
Max Williams
14 Мар 2014 в 19:21
Извините, сегодня пятница, и мой мозг поджарился. Страница кэширует результаты. Если вы измените статус определенного тикета, он не будет отображаться в результатах, пока вы не перезапустите сервер. Если я изменю метод сортировки на Ticket.order(:status), как это предлагается ниже, все будет работать нормально.
 – 
paulkennethkent
14 Мар 2014 в 20:03

Возможное решение

1. Определите 3 области

scope :status_o,  lambda { where(:status => "open") }
scope :status_p,  lambda { where(:status => "paused") }
scope :status_c,  lambda { where(:status =>  "closed") }

2. используйте это как-то

tickets = Ticket.status_o
tickets<<Ticket.status_p
tickets<<Ticket.status_c
0
lx00st 14 Мар 2014 в 17:03