#ruby-on-rails
#ruby-on-rails
Вопрос:
У меня есть модель, которая имеет рекурсивную ссылку на саму себя, например, связанный список. Если я пишу функцию, подобную приведенной ниже (простите за мой синтаксис, Ruby — не мой любимый язык), чтобы следовать цепочке до конца. Предполагая, что это часть модели активной записи и next
является внешним ключом к следующему узлу, что происходит за кулисами для этой функции? Сколько отдельных подключений к моей базе данных MySQL открывается активной записью и как долго они сохраняются?
module LinkedList
class Node < ActiveRecord::Base
has_one :value
has_one :next, foreign_key: 'id' class_name: 'Source::Incident'
def fetch_all_nodes(current_node=nil, all_nodes=nil)
current_node = current_node ? current_node : self
all_nodes = all_nodes ? all_nodes : [self]
if current_node.next
all_nodes = fetch_all_nodes(current_node.next, all_nodes << current_node)
all_nodes
end
end
end
Комментарии:
1. Можете ли вы также добавить свое базовое определение модели?
2. Немного уточнил — это должен быть простой гипотетический пример, поэтому, если потребуется больше деталей, пожалуйста, дайте мне знать!
Ответ №1:
Поскольку он написан как рекурсивная функция, у вас будет один SQL-вызов call на узел. Вызывается Next, получает связанные узлы и кэширует значение. (При необходимости вы можете перезагрузить его). Насколько я могу судить, эта реализация заканчивается одним объектом для каждой записи базы данных. Если бы вы в конечном итоге искали объект, который вы уже сохранили, это вызвало бы больше объектов и больше запросов к базе данных, но Rails имеет кэш запросов, так что это может сократить такие запросы.
Вы могли бы all_nodes
вместо этого вернуть отложенный перечислитель, и тогда, если вы в конечном итоге не проверите весь хвост, у вас будет только один вызов на посещенный узел, и вы могли бы обрабатывать потенциально бесконечные (или даже циклические) списки.
Ответ №2:
ActiveRecord
используется ActiveRecord::ConnectionAdapters::ConnectionPool
для подключения к вашему хранилищу данных, пул которого по умолчанию состоит из 5 подключений. Таким образом, максимум, каждый экземпляр Rails / ActiveRecord будет использовать максимальное количество подключений к базе данных в качестве настроенного размера пула подключений.