Reputation: 5250
I have two models with has_many through
associations; Taskflows
and Datasets
. They has a join table called DatasetAssignments
.
I get all Taskflows using:
@taskflows = Taskflows.all
I know it's possible to get associations from a single ActiveRecord object, eg:
@taskflow.datasets
but is it possible to get all associated Datasets
from the @taskflows
ActiveRecord collection? Such as @taskflows.datasets
Any help would be much appreciated.
Models:
class Dataset < ActiveRecord::Base
has_many :dataset_assignments
has_many :taskflows, :through => :dataset_assignments
end
class Taskflow < ActiveRecord::Base
has_many :dataset_assignments
has_many :datasets, :through => :dataset_assignments
end
class DatasetAssignment < ActiveRecord::Base
belongs_to :dataset
belongs_to :taskflow
end
Upvotes: 5
Views: 9249
Reputation: 5156
Given that @taskflows
is an ActiveRecord::Relation
, you can do this:
@datasets = Dataset.joins(:dataset_assignments).
where(dataset_assignments: {taskflow: @taskflows.joins(:datasets) })
or, in the other direction:
@taskflows = Taskflow.joins(:dataset_assignments).
where(dataset_assignments: {dataset: @datasets.joins(:taskflows) })
joins
generates INNER JOIN
s through many-to-many table and having the receiver being an instance of ActiveRecord::Relation
will preserve other conditions.
As @oreoluwa suggested, you can avoid N+1 queries when enumerating by using includes
:
@taskflows = Taskflow.joins(...).includes(:datasets)
Upvotes: 7
Reputation: 5623
I don't think there is a way to do this, unless you have an outer model, let's call it User, where:
User
has_many :taskflows
has_many :datasets, through: :taskflows
or better let your DatasetAssignment
belong to the user and fetch all dataset_assignments
of a particular User.
Another approach would be to do a @taskflows.map(&:datasets)
, but it's not effecient.
Or if you only need the datasets
to render somewhere and are bothered about effeciency, you should use the AR#includes
method like:
@taskflow.includes(:datasets)
Upvotes: 0