如何从活动记录集合中获取所有has_many关联

时间:2016-06-30 14:48:54

标签: ruby-on-rails database ruby-on-rails-4 activerecord

我有两个has_many through关联的模型; TaskflowsDatasets。他们有一个名为DatasetAssignments的连接表。

我使用以下命令获取所有任务流:

@taskflows = Taskflows.all

我知道可以从单个ActiveRecord对象获取关联,例如:

@taskflow.datasets

但是可以从Datasets ActiveRecord集合中获取所有关联的@taskflows吗?例如@taskflows.datasets

非常感谢任何帮助。

型号:

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

2 个答案:

答案 0 :(得分:6)

鉴于@taskflowsActiveRecord::Relation,您可以这样做:

@datasets = Dataset.joins(:dataset_assignments).
    where(dataset_assignments: {taskflow: @taskflows.joins(:datasets) })

或者,在另一个方向:

@taskflows = Taskflow.joins(:dataset_assignments).
    where(dataset_assignments: {dataset: @datasets.joins(:taskflows) })

joins通过多对多表生成INNER JOIN,并且接收者是ActiveRecord::Relation的实例将保留其他条件。

正如@oreoluwa建议的那样,使用includes枚举时可以避免N + 1个查询:

@taskflows = Taskflow.joins(...).includes(:datasets)

答案 1 :(得分:0)

我认为没有办法做到这一点,除非你有一个外部模型,让我们称之为用户,其中:

User
  has_many :taskflows
  has_many :datasets, through: :taskflows

或者更好地让您的DatasetAssignment属于该用户并获取特定用户的所有dataset_assignments

另一种方法是做@taskflows.map(&:datasets),但效率不高。

或者,如果您只需要datasets来渲染某个地方并且对效率感到困扰,那么您应该使用AR#includes方法,例如:

@taskflow.includes(:datasets)