Это не ужасная идея, но и не очень хорошая. Это не совсем соответствует тому, как Rails делает вещи. Во-первых, вы получите много уродливого постоянного кода. Слишком много ALL_CAPS_WORDS, и ваш Ruby начинает выглядеть как C ++. Bleah.
Для другого это негибко. Собираетесь ли вы сделать одну из этих констант для каждой категории? Если вы добавите новую категорию через два месяца, не забудете ли вы обновить код Rails, добавить новую константу, повторно развернуть ее и перезапустить сервер?
Если для вас важно иметь возможность легко получать доступ к категориям, а не повторять запросы к БД, вот немного метапрограммирования, которое автоматически их ищет и создает статические методы, подобные Лихтамбергу, для вас при первом доступе:
def self.method_missing(category, *args) # The 'self' makes this a class method
@categories ||= {}
if (@categories[category] = find_by_name(category.to_s))
class_eval "def self.#{category.to_s}; @categories[#{category}]; end"
return @categories[category]
end
super
end
С этим методом при каждом вызове Category.ham
будет создан метод класса, который возвращает значение find_by_name("ham")
, так что ни запрос, ни method_missing()
не будут выполняться снова при следующем вызове Это. Это в значительной степени так работает класс OpenStruct , кстати; если хотите узнать больше, посмотрите в книге «Кирка».
(Конечно, у вас все еще есть риск, что, поскольку все они запомнены, ваше приложение Rails не будет отражать любые изменения, которые вы вносите в объекты своей категории. Это предполагает, что изменения не произойдут или не произойдут Это действительно важно. Вам решать, является ли это предположение допустимым для вашего приложения. Вы всегда можете добавить в свой код обратный вызов after_update
, который сбрасывает @@categories
, если это проблема, но в этот момент это становится сложным .)