In my rails app, collections have many projects, and projects have many steps.
I'd like to grab all the ids of steps in a collection's projects, and I'm wondering if I can do it all in one query.
For example, I know I can do the following
step_ids = []
@collection.projects.each do |project|
project.steps.each do |step|
step_ids << step.id
end
end
But is it possible to do something like the following:
@collection.projects.include(:steps).pluck("step.id")
// syntax here is not correct
Prefer pluck instead of map Using pluck will be faster, because it doesn't need to load an entire object into memory. For this particular case, pluck is six times faster than map .
What the pluck () function does is that it essentially loops through a collection and collects all the data from the particular field and stores it in another collection. That would mean, it plucks the concerned value from a large set of data and stores them in a separate collection for later usage.
Try this:
Step.joins(:project).where(projects: { collection_id: @collection.id }).pluck(:'steps.id')
Note the use of project
for the joins, and then projects
for the where clause. The first corresponds to the belongs_to relationship, and the latter is the name of the db table.
edit: in the case of a many-to-many relationship between projects and collections, and assuming a project belongs_to a project_collection (and then has_many :collections, through :project_collection
)
Step.joins(:project => :project_collection)
.where(project_collections: { collection_id: @collection.id })
.pluck(:'steps.id')
Unfortunately, I don't think that we could do it through AR in a single query. You could do a nested query below to retrieve it in two queries to the database:
Step.includes(:projects)
.where(projects: { id: Projects.includes(:collections)
.where(collections: { id: @collections.id }).pluck(:id) } )
.pluck(:id)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With