import itertools
foos=[1.0, 2.0, 3.0, 4.0, 5.0]
bars=[1, 2, 3]
print zip(foos, itertools.cycle([bars]))
Переключитесь на целое число, как сказал Аарон, тогда вы, вероятно, захотите использовать default_scope .
Например:
class Task < ActiveRecord::Base
default_scope :order => 'tasks.position' # assuming the column name is position
...
С областью действия по умолчанию вы выиграли ' При любом вызове метода поиска необходимо указывать порядок сортировки - задачи будут отсортированы автоматически.
Я бы использовал целые числа в базе данных. Легче сортировать и индексировать, а затем переопределить средство получения и установки атрибута, чтобы использовать символы для внешнего интерфейса.
Вы можете использовать оператор 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 вы можете добавить столбец позиции в виде целого числа, по которому вы можете сортировать, и существуют плагины, чтобы упростить это.
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
).
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
the approach might not be flexible enough, but too me, I try not to generalize the problem unless it is necessary
Я бы предложил использовать actions_as_list ( http://github.com/rails/acts_as_list/tree/master ), который добавит поле позиции к вашему объекту, но также предоставит вам все методы для перемещения элементов вверх и вниз по списку при правильном сохранении порядка.
Если приоритеты никогда не изменятся, может быть лучше сделайте приоритетным поле в таблице задач. Проблема в том, что вам нужно иметь возможность сортировки по приоритету. Для этого у вас есть несколько вариантов, но что бы вы ни выбрали, это должно выполняться db.