Направляющие: Пользовательское упорядочивание записей

import itertools

foos=[1.0, 2.0, 3.0, 4.0, 5.0]
bars=[1, 2, 3]

print zip(foos, itertools.cycle([bars]))
21
задан Homar 30 August 2009 в 13:54
поделиться

6 ответов

Переключитесь на целое число, как сказал Аарон, тогда вы, вероятно, захотите использовать default_scope .

Например:

class Task < ActiveRecord::Base
  default_scope :order => 'tasks.position' # assuming the column name is position
  ...

С областью действия по умолчанию вы выиграли ' При любом вызове метода поиска необходимо указывать порядок сортировки - задачи будут отсортированы автоматически.

4
ответ дан 29 November 2019 в 06:49
поделиться

Я бы использовал целые числа в базе данных. Легче сортировать и индексировать, а затем переопределить средство получения и установки атрибута, чтобы использовать символы для внешнего интерфейса.

5
ответ дан 29 November 2019 в 06:49
поделиться

Вы можете использовать оператор case в предложении where. Это немного некрасиво, но должно сработать:

class Task
  PRIORITIES_ORDERED = ['high', 'medium', 'low']

  # Returns a case statement for ordering by a particular set of strings
  # Note that the SQL is built by hand and therefore injection is possible,
  # however since we're declaring the priorities in a constant above it's
  # safe.
  def self.order_by_case
    ret = "CASE"
    PRIORITIES_ORDERED.each_with_index do |p, i|
      ret << " WHEN priority = '#{p}' THEN #{i}"
    end
    ret << " END"
  end

  named_scope :by_priority, :order => order_by_case

end

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

Task.all.by_priority

Конечно, как уже упоминали другие люди, лучше сделать внешний ключ для таблицы приоритетов вместо столбца текстовой строки. В таблице Priorty вы можете добавить столбец позиции в виде целого числа, по которому вы можете сортировать, и существуют плагины, чтобы упростить это.

26
ответ дан 29 November 2019 в 06:49
поделиться

If changing your schema to use an integer priority isn't an option, you can also define a custom <=> method on Task to define the sort order.

class Task

  PRIORITIES = {
    :high => 3,
    :med  => 2,
    :low  => 1,
  }

  def <=> (other)
    PRIORITIES[self.priority] <=> PRIORITIES[other.priority]
  end

end

The downside of doing it this way is that you'll need to do the sorting on the Ruby side, rather than let your database do it for you, which will preclude the use of default_scope. The upside is that any time you call sort on an Array of Tasks the order will come out correctly (or, if you only want a custom ordering in one particular place, you can use sort_by).

4
ответ дан 29 November 2019 в 06:49
поделиться

Just to solve your specific question: You can order it by the last letter.

Sever(e), Hig(h), Mediu(m), Lo(w)

you can either do it in rails or sql:

order by RIGHT(priority, 1)

I choose this approach because

  1. it is the easiest possible way.
  2. you mentioned it is not going to change.

the approach might not be flexible enough, but too me, I try not to generalize the problem unless it is necessary

2
ответ дан 29 November 2019 в 06:49
поделиться

Я бы предложил использовать actions_as_list ( http://github.com/rails/acts_as_list/tree/master ), который добавит поле позиции к вашему объекту, но также предоставит вам все методы для перемещения элементов вверх и вниз по списку при правильном сохранении порядка.

Если приоритеты никогда не изменятся, может быть лучше сделайте приоритетным поле в таблице задач. Проблема в том, что вам нужно иметь возможность сортировки по приоритету. Для этого у вас есть несколько вариантов, но что бы вы ни выбрали, это должно выполняться db.

1
ответ дан 29 November 2019 в 06:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: