Rails 6 adds Relation#extract_associated

1 minute read

Rails 6 has added ActiveRecord::Relation#extract_associated for extracting associated records from a relation.

Before

Trying to access collections from related collections on objects, is a common use case in many applications. A simple example is if we want to fetch all authors of posts from a given category . Previously, if we wanted to extract such associated records from a relation we would make use of preload and collect .

> category . posts . preload ( :author ). collect ( & :author ) Post Load ( 4.8 ms ) SELECT "posts" . * FROM "posts" WHERE "posts" . "category_id" = ? [[ "category_id" , 2 ]] Author Load ( 3.5 ms ) SELECT "authors" . * FROM "authors" WHERE "authors" . "id" IN ( ?, ?, ?) [[ "id" , 1 ], [ "id" , 2 ], [ "id" , 3 ]] => [ #<Author id: 1, name: "David", created_at: "2019-08-16 06:26:29", updated_at: "2019-08-16 06:26:29">, #<Author id: 2, ...]

This usage of preload(:author).collect(&:author) can get repetitive and does not describe the intent of usage properly.

extract_associated method

Relation#extract_associated has now been introduced as a shorthand for preload and collect . It extracts a named association from the relation. The named association is first preloaded, then the individual association records are collected from the relation.

> category . posts . extract_associated ( :author ) Post Load ( 0.2 ms ) SELECT "posts" . * FROM "posts" WHERE "posts" . "category_id" = ? [[ "category_id" , 2 ]] Author Load ( 0.2 ms ) SELECT "authors" . * FROM "authors" WHERE "authors" . "id" IN ( ?, ?, ?) [[ "id" , 1 ], [ "id" , 2 ], [ "id" , 3 ]] => [ #<Author id: 1, name: "Sam", created_at: "2019-08-16 06:26:29", updated_at: "2019-08-16 06:26:29">, #<Author id: 2, name: "Matt", created_at: "2019-08-16 06:26:32", updated_at: "2019-08-16 06:26:32">, #<Author id: 3, name: "John", created_at: "2019-08-16 06:26:35", updated_at: "2019-08-16 06:26:35">]

extract_associated returns collection of associated collections in case of belongs_to and has_many associations.