rails + ActiveRecord: кэширование всех регистров модели
У меня есть крошечная модель (назовем ее "Узел"), которая представляет древовидную структуру. Каждый узел содержит только имя и ссылку на своего отца:
class Node < ActiveRecord::Base
validates_presence_of :name, :parent_id
end
Таблица не очень большая - менее 100 элементов. Он обновляется редко - за последние 4 месяца администратором сайта было добавлено 20 новых элементов.
Тем не менее, он довольно часто используется в моем приложении. Учитывая его древовидную структуру, в некоторых случаях запрос вызывает более 30 обращений к базе данных (включая вызовы ajax, которые я использую довольно часто).
Я хотел бы использовать какое-то кэширование, чтобы уменьшить доступ к базе данных - поскольку таблица очень мала, я подумал о кэшировании всех регистров в памяти.
Это возможные рельсы 2.3? Есть ли лучший способ справиться с этим?
3 ответа
Почему бы вам просто не загружать их каждый раз, чтобы избежать попадания нескольких нагрузок?
Вот простой пример:
before_filter :load_all_nodes
def load_all_nodes
@nodes = Node.all.inject({ }) { |h, n| h[n.id] = n; n }
end
Это даст вам хэш, индексированный по Node # id, чтобы вы могли использовать этот кеш вместо вызова find:
# Previously
@node = Node.find(params[:id])
# Now
@node = @nodes[params[:id].to_i]
Для небольших простых записей их загрузка в один прием - довольно недорогая операция.
Вы смотрели на любой из плагинов, которые дают поведение, похожее на дерево?
У Райана Бейтса есть Railscast на activ_as_tree, однако activ_as_nested_set или один из других вдохновленных им проектов, таких как awesome_nested_set или acts_as_better_nested_set, может лучше подойти для ваших нужд.
Эти проекты позволяют вам получить узел и все его дочерние элементы одним SQL-запросом. На сайте activ_as_better_nested_set есть хорошее описание того, как работает этот метод.
Посмотрев несколько мест, я думаю, что решение Тадмана самое простое.
Для более гибкого решения я нашел эту суть:
С уважением!