Rails - 如何在多对多关系中列出每个对象的对象?

时间:2016-02-25 11:41:03

标签: ruby-on-rails ruby many-to-many

我有多个具有连接表的模型,我想在控制器中实现这些项的列表。

Customer <- many -> Products
Products <- many -> Teams
Products <- many -> Documents

型号:

class Customer < ActiveRecord::Base
   has_many :cstprd_relations
   has_many :products, :through => :cstprd_relations
end

class Product < ActiveRecord::Base
  has_many :cstprd_relations
  has_many :customers, :through => :cstprd_relations

  has_many :teaprd_relations
  has_many :teams, :through => :teaprd_relations
end

class Team < ActiveRecord::Base
  has_many :teaprd_relations
  has_many :products, :through => :teaprd_relations
end

class Document < ActiveRecord::Base
  has_many :prddoc_relations
  has_many :products, :through => :prddoc_relations
end

例如,文档迁移:

class CreateDocuments < ActiveRecord::Migration
  def change
    create_table :documents do |t|
      t.string :name

      t.timestamps null: false
    end
  end
end

class AddDocumentRefToProducts < ActiveRecord::Migration
  def change
    add_reference :products, :document, index: true, foreign_key: true
  end
end

如何列出属于产品的独特文档并将它们(文档)链接到团队?

像这样:

customer1表:

  • 产品'Calc'的文档'测试阶段1'由团队完成 'QA,TestTeam,Dev'“
  • “产品'电话'的文档'测试阶段2'由团队完成 'QA,TechSpec,MarketingTeam'“
  • “产品'应用'的文档'安装指南'由团队'Dev,TechSpec'完成”

2 个答案:

答案 0 :(得分:1)

我不确定我是否理解这个问题,但您可以将ActiveRecord关联与where子句混合匹配,如下所示:

team_4_documents = Document.where(product_id: Team.find(4).products).all

(.find(4)这里是使团队成为特定团队的一个例子)

答案 1 :(得分:1)

也许此代码显示它的外观。

Product.all.each do | prod |
  Document.products( prod.id ).teams.each do | team |
    # generate message
  end 
end

或基于文件

Document.where( :id => id ).each do | doc |
  doc.products.each do | prod |
    prod.teams.each do | team |
      # generate you message
    end
  end
end

修改的 回答评论中的问题

Customer.all.each do | cust |
  puts "Customer #{cust.name}"
  cust.products.each do | prod |
    prod.documents.each do | doc |
      print "* Document #{doc.name} for product #{prod.name} is finished by teams "
      puts "'" + prod.teams.map(&:name).join(', ') + "'"
    end 
  end
end