4

というクラスがありLocationます。単一のクエリ内ですべての直接の子をプリロードしたいと思います。

クラス関係では、次のようにLocation定義されます。

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>, (...)]

しかし、これを最適化し、すべてを 2 つのバッチでロードしたい場合:

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'

これは Rails のバグですか、それとも別の方法で定義する必要がありますか?

また、リレーションで find_in_collection を上書きしようとしていますが、影響はありません。

4

1 に答える 1