Can I use a find_each query with an include statement?

Example:

Foobar.joins(:baz).includes(:baz).count
=> 22926
Foobar.joins(:baz).includes(:baz).find_each.count
=> 998
Foobar.joins(:baz).find_each.count
=> 22926

The generated sql in the right case (third) is a few sql packages that look like this:

SELECT  "foobar".* FROM "foobar" INNER JOIN "baz" ON 
"baz"."foobar_id" = "foobar"."id" ORDER BY "foobar"."id" ASC LIMIT $1

in case of failure (second) there is one request that looks like this:

SELECT  "foobar"."id" AS t0_r0
 "baz"."id" AS t1_r0
 "baz"."foobar_id" AS t1_r1
 FROM "foobar" INNER JOIN "baz" ON "baz"."foobar_id" = "foobar"."id" 
 ORDER BY "foobar"."id" ASC LIMIT $1

where all fields are listed as another temporary variable (for example, t0_r0) for different columns in each table (in the actual query there are 37 sections 30 on the first object, 7 on the second).

This is mistake? includesnot allowed in the request find_each? Am I doing something wrong?

The relationships between Foobarand Bazare equal to Foobar has_one Bazand Baz belongs_to Foobar.

+4
source share
1 answer

, has_one has_one.

, baz.foobar_id. , Foobar, Baz:

baz.id | baz.foobar_id
------   -------------
1        1
2        1
3        2

joins Foobar Baz:

Foobar.joins(:baz).count  # This would be 3

, find_each join Foobar:

Foobar.joins(:baz).find_each(batch_size: 2) { |f| puts f.id }
# SELECT  "foobar".* FROM "foobar" INNER JOIN "baz" ON... LIMIT 2
1
1
# SELECT  "foobar".* FROM "foobar" INNER JOIN "baz" ON... WHERE ("foobar"."id" > 1) ... LIMIT 2
2

includes , Rails Foobar. , find_each :

Foobar.joins(:baz).includes(:baz).find_each(batch_size: 2) { |f| puts f.id }
# SELECT  "foobar"."id" AS t0_r0 ... LIMIT 2
1

find_each , , , :

# ActiveRecord::Batches#in_batches
break if ids.length < batch_limit

find_each 1000. 998 . , 998 Foobar, , find_each , . , 1000 Baz, 998 Foobar.

baz, , . - :

Baz.group(:foobar_id).having('count(*) > 1')

, has_one. , Foobar - :

Foobar.group(:id).joins(:baz).includes(:baz).count
Foobar.group(:id).joins(:baz).includes(:baz).find_each.count
Foobar.group(:id).joins(:baz).find_each.count
+1

Source: https://habr.com/ru/post/1674292/


All Articles