【问题标题】:How to get all has_many associations from an active record collection如何从活动记录集合中获取所有 has_many 关联
【发布时间】:2016-06-30 14:48:53
【问题描述】:

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

我使用以下方式获取所有任务流:

@taskflows = Taskflows.all

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

@taskflow.datasets

但是是否可以从@taskflows ActiveRecord 集合中获取所有关联的Datasets?如@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

【问题讨论】:

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


    【解决方案1】:

    鉴于@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 JOINs,并且将接收者作为ActiveRecord::Relation 的实例将保留其他条件。

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

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

    【讨论】:

    • 谢谢,@datasets.joins(:taskflows)@datasets.joins(@taskflows) 之间有区别吗 - @taskflows 来自上一个查询?
    • 等等,这有问题。您将获得与接收者相同的课程记录。当@datasets 是接收者时,数据集就是你得到的,但你需要任务流。
    【解决方案2】:

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

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

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

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

    或者如果您只需要 datasets 在某处渲染并且担心效率问题,您应该使用 AR#includes 方法,例如:

    @taskflow.includes(:datasets)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多