如何实现RoR多对多关系?`

时间:2011-07-07 22:15:38

标签: ruby-on-rails activerecord

我有以下型号:

Technician
- id
- name
- personal_id

Tool
- id
- internal_code
- name
- category

技术人员可以拥有许多工具,并且可以为许多技术人员分配一个工具(我真的需要多对多的关系,因为我输入这个我有疑虑)。我的问题是我还需要跟踪技术人员拥有的工具数量。一条记录应该像[technician_id,tool_id,quantity]。我已经阅读了关于has_many的内容,但是我还没有看到一个适合我的问题的示例,结果表的结构应该是什么,以及我应该如何为技术人员拥有的工具设置模型?

2 个答案:

答案 0 :(得分:3)

听起来这是使用HABTM关系类型的完美场所。您将要执行以下操作:

运行以下迁移:

class AddTechniciansToolsJoinTable < ActiveRecord::Migration
  def self.up
    create_table :technicians_tools, :id => false  do |t|
      t.integer :technician_id, :null => :false
      t.integer :tool_id, :null => :false
    end
    add_index :technicians_tools, [:technician_id, :tools_id], :unique => true
  end

  def self.down
    drop_table :technicians_tools
  end
end

将以下内容添加到模型中:

class Technician < ActiveRecord::Base
  has_and_belongs_to_many :tools
end

class Tool < ActiveRecord::Base
  has_and_belongs_to_many :technicians
end

这将允许您使用许多特定于HABTM关系的Rails方法(例如technician.tools.size)来计算该特定技术人员可用的工具。

有关详细信息,请在此处查看有关HABTM关系的Rails指南:http://edgeguides.rubyonrails.org/association_basics.html#has_and_belongs_to_many-association-reference

答案 1 :(得分:2)

好像你正在寻找一个多对多的关联。 根据您设定的要求,这应该适合您:

class Technician < ActiveRecord::Base
  has_many :assignments
  has_many :tools, :through => :assignments
end

class Tool < ActiveRecord::Base
  has_many :assignments
  has_many :technicians, :through => :assignments
end

class Assignment < ActiveRecord::Base
  belongs_to :tool
  belongs_to :technician
end

希望它有所帮助。


<强>更新

考虑到您对Assignments中的数量字段的评论,我假设您希望能够将许多相同的Tool分配给Technician。例如:

>> Technician.new(:name => "Bob").save
=> true
>> Tool.new(:name => "hammer").save
=> true
>> Tool.new(:name => "saw").save
=> true
>> t = Technician.first
=> #<Technician id: 1, name: "Bob", personal_id: nil, created_at: "2011-07-07 22:56:53", updated_at: "2011-07-07 22:56:53">
>> t.tools << [Tool.first, Tool.last]
=> [#<Tool id: 1, name: "hammer", internal_code: nil, category: nil, created_at: "2011-07-07 22:56:22", updated_at: "2011-07-07 22:56:22">, #<Tool id: 2, name: "saw", internal_code: nil, category: nil, created_at: "2011-07-07 22:56:30", updated_at: "2011-07-07 22:56:30">]
>> t.save
=> true
>> t.assignments
=> [#<Assignment id: 1, technician_id: 1, tool_id: 1, quantity: nil, created_at: "2011-07-07 23:01:53", updated_at: "2011-07-07 23:01:53">, #<Assignment id: 2, technician_id: 1, tool_id: 2, quantity: nil, created_at: "2011-07-07 23:02:46", updated_at: "2011-07-07 23:02:46">]
>> a = t.assignments.first
=> #<Assignment id: 1, technician_id: 1, tool_id: 1, quantity: nil, created_at: "2011-07-07 23:01:53", updated_at: "2011-07-07 23:01:53">
>> a.quantity = 5
=> 5
>> a.save
=> true
>> t.assignments.first.quantity
=> 5
>> 

如果不是这种情况,请告诉我&amp;我可以用另一种方法更新。