Unwanted load relationship when the ratio is determined by finder_sql - ignores finder_sql and creates a default request has_many

There is a class called Location . I would like to preload all direct children in one request.

In Location , the class relation is defined as follows:

 has_many :children, class_name: self, finder_sql: ->(query) { self.class.where(%Q{"locations"."ancestry" like '%#{id}'}).to_sql }, counter_sql: ->(query) { self.class.where(%Q{"locations"."ancestry" like '%#{id}'}).count.to_sql } Location.first.children Location Load (0.4ms) SELECT "locations".* FROM "locations" LIMIT 1 Location Load (0.3ms) SELECT "locations".* FROM "locations" WHERE ("locations"."ancestry" like '%1') => [#<Location id: 2, code: nil, name: "Niger 1349875728.873964", alternative_name: nil, ancestry: "1", coordinates: nil, ancestry_depth: 1>, (...)] 

But when I want to optimize this and download everything in just two batches:

 Location.includes(:children).where(id: [5, 100]).all Location Load (0.4ms) SELECT "locations".* FROM "locations" WHERE "locations"."id" IN (5, 100) Location Load (0.2ms) SELECT "locations".* FROM "locations" WHERE "locations"."location_id" IN ('5') ActiveRecord::StatementInvalid: PG::Error: ERROR: column locations.location_id does not exist LINE 1: SELECT "locations".* FROM "locations" WHERE "locations"."lo... ^ : SELECT "locations".* FROM "locations" WHERE "locations"."location_id" IN ('5') from /xxx/.rvm/gems/ ruby-1.9.3-p194@gsp /gems/activerecord-3.2.8/lib/active_record/connection_adapters/postgresql_adapter.rb:1158:in `async_exec' 

Is this a bug in Rails, or should I define it differently?

I am also trying to overwrite find_in_collection with respect, but this has no effect.

+4
source share
1 answer

Yes, you fight with Rails too much. Use the condition parameter on has_many:

 has_many :children, class_name: self, conditions: [%Q{"locations"."ancestry" like '%#{id}'}] 

Also just wondering about using similar ones there? Why not check for =?

 has_many :children, class_name: self, foreign_key: :ancestry 

Also, to style _id if you go this route:

 has_many :children, class_name: self, foreign_key: :ancester_id 
0
source

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


All Articles