Uma ação do controlador que cria vários objetos dentro de um loop é candidata para consultas N+1. No entanto, o segmento a seguir
shop_id = section.shop_id
section_id = section.id
serving_table_id = section.serving_table.id
range = 1..i
range.each do |i|
@cover = Cover.create(shop_id: shop_id, section_id: section_id, serving_table_id: serving_table_id, name: i )
end
evento embora os atributos a serem salvos sejam definidos antes do bloco de iteração,
está gerando via prosopite
gem uma detecção de consulta N+1,
para cada um dos objetos shop, parti e serving_table.
Não sendo uma consulta para uma coleção, includes
seria inaplicável.
Como evitar consultas N+1 neste caso?
O
ActiveRecord::Base#insert_all
( https://apidock.com/rails/v7.1.3.4/ActiveRecord/Persistence/ClassMethods/insert_all ) pode receber uma matriz de hashes para criarTenha cuidado com a reversão de instruções caso uma seja inválida.
Você está erroneamente assumindo que existe uma única solução simples e definitiva para esse cenário mal definido.
Consultas N+1 em leitura são um problema relativamente simples de resolver, pois você pode simplesmente carregar as linhas relacionadas por meio de uma junção ou de uma consulta separada com poucos efeitos colaterais.
Lidar com registros de inserção/atualização/subinserção em massa não é um problema fácil.
Você precisa considerar cuidadosamente se pode abrir mão de validações e retornos de chamada e usar
insert_all
/update_all
/upsert_all
em uma única consulta ou se realmente precisa manipular cada registro separadamente.Os principais fatores para decidir aqui são se a operação está lidando com entrada do usuário e pode falhar, como você vai lidar com os erros e os requisitos de desempenho.
Então você precisa considerar se isso pode ser transferido para uma tarefa em segundo plano para que o web head (e o usuário por trás da tela) não precisem esperar a conclusão, o que aumenta a dor de cabeça de lidar com um processo assíncrono.