The following method is invoked for a collection. It handles only integers:
def create_txrow( parti_id, paying_consumer_id, nation_vat_id )
puts nation_vat_id
puts nation_vat_id.class
puts parti_id
puts parti_id.class
new_row = Txrow.create(
nation_vat_id: nation_vat_id,
paying_consumer_id: paying_consumer_id,
parti_id: parti_id,
[...]
The console output returns as expected
1
Integer
2
Integer
Yet the log shows for each iteration of this method
↳ app/controllers/concerns/taxation_methods.rb:253:in `create_txrow'
NationVat Load (0.5ms) SELECT "nation_vats".* FROM "nation_vats" WHERE "nation_vats"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳ app/controllers/concerns/taxation_methods.rb:253:in `create_txrow'
Parti Load (0.6ms) SELECT "partis".* FROM "partis" WHERE "partis"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
↳ app/controllers/concerns/taxation_methods.rb:253:in `create_txrow'
Line 253 referes specifically to new_row = Txrow.create(
line.
Thus these queries are being made to the database, but nothing in the code is requesting it... the integers should be nominally be fed to the method.
To avoid the N+1 problem, the collection is instantiated by a query that specifies
.includes( :parti, :shopvat
in order to then select on the basis of the member of that collection
shopvat_for_item = shopvats.select{ |i| i.id = item.shopvat_id }.first
and generate
the call to this method with
new_txrow = create_txrow( item.parti_id, item.cover.consumer_id, shopvat_for_item.nation_vat_id)
.
What could possibly trigger two db queries (while not the third!)
These checks are for referential integrity. They ensure that the NationVat
and the Parti
exist based on the belongs_to
relationship.
If you don't want this validation (which seems like a bad idea in this case) you can set optional: true
on the belongs_to
relationship.
class Txrow < ApplicationRecord
belongs_to :nation_vat, optional: true
belongs_to :parti, optional: true
end
Again given that Txrow
seems to be an associative join between the NationVat
and the Parti
objects, I would not recommend making these optional but this will stop the queries you are seeing.