Skip to content

Add ActiveRecord::Relation#extract_associated for extracting associated record - #35784

Merged
dhh merged 4 commits into
masterfrom
extract-associated
Mar 29, 2019
Merged

Add ActiveRecord::Relation#extract_associated for extracting associated record#35784
dhh merged 4 commits into
masterfrom
extract-associated

Conversation

@dhh

@dhh dhh commented Mar 28, 2019

Copy link
Copy Markdown
Member

It's sometimes more convenient to access a certain set of records by going through a scoped relation and its associations. It's easy enough to do this today using #preload and #collect, but it's repetitive and not descriptive of the intent.

This is where #extract_associated comes in. Like so:

account.memberships.extract_associated(:user)

Which is short-hand for and describing the intent of:

account.memberships.preload(:user).collect(&:user)


def test_extracted_association
authors = Post.all.extract_associated(:author)
assert_equal Post.all.collect(&:author), authors

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should wrap the extract in an assert_queries 1, such that we test the preload query optimization.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea!

@simi

simi commented Mar 28, 2019

Copy link
Copy Markdown
Contributor

🤔 what about load_associated?

@dhh

dhh commented Mar 29, 2019 via email

Copy link
Copy Markdown
Member Author

@simi

simi commented Mar 29, 2019

Copy link
Copy Markdown
Contributor

I'm just trying to find out something similar in current method names since extract is not common term in ActiveRecord terminology. There's already load method and that was origin of my initial idea.

I understand this as a pluck of association on relation. My second idea was pluck_associated, but it sounds a little strange me. 🤔

@rafbm

rafbm commented May 3, 2019

Copy link
Copy Markdown
Contributor

As it is, I feel extract_associated brings little gain, especially as it only “supports” belongs_to and has_one associations. It would be a much more meaningful addition if it also supported has_many, ie. changing collect to flat_map under the hood.

I actually think the current behavior can be quite confusing. As the doc states, extract_associated returns a “collection of X records”:

account.memberships.extract_associated(:user)
# => Returns collection of User records

You could easily expect the following to return a “collection of Comment records”:

category.posts.extract_associated(:comments)

…but you’d be wrong, as this will instead return a “collection of Comment collections”.

suketa added a commit to suketa/rails_sandbox that referenced this pull request Sep 27, 2019
Add `ActiveRecord::Relation#extract_associated` for extracting associated record
rails/rails#35784
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants