在RoR中,如何在两个表之间创建两个一对一的关系?

时间:2010-12-26 22:25:50

标签: ruby-on-rails activerecord

在RoR3中,

我拥有用户和技能,每项技能都由用户创建。我想记录下来,所以我建立了一对多的关系。

class User < ActiveRecord::Base
  has_many :skills
end

class Skill < ActiveRecord::Base
  belongs_to :user
end

然而,每个用户也有很多技能,用户“Bob”创造技能“功夫”,用户“Charlie”创造技能“空手道”和用户“Bob”都创建并且能够做到这两点“功夫“和”空手道“

我应该如何用ActiveRecord表示这个?我应该创建一个新表“user_skills”has_many:技能?和belongs_to:用户?

3 个答案:

答案 0 :(得分:4)

这里有两种不同的联想。第一个是一对多关联。用户可以是任意数量技能的创建者。第二个是多对多关联,用户可以拥有许多技能,而技能可以拥有许多用户。

第一个是简单的belongs_to <-> has_many声明。对于第二个,您需要在两个模型中都需要has_and_belongs_to_many声明,以及相关的连接表,或专用连接模型以及has_many :through声明。让我们试试第一个:

方法1:HABTM

class User < ActiveRecord::Base
  has_many :created_skills, :class_name => 'Skill', :inverse_of => :creator
  has_and_belongs_to_many :skills
end

class Skill < ActiveRecord::Base
  belongs_to :creator, :class_name => 'User', :inverse_of => :created_skills
  has_and_belongs_to_many :users
end

这需要一个名为“skills_users”的连接表,其中包含名为user_idskill_id

的列

方法2:有很多通过(加入模型)

第二个类似,但添加了一个充当中间人的模型。这有一个额外的好处,您可以在连接模型中包含其他列,例如技能级别。

class User < ActiveRecord::Base
  has_many :created_skills, :class_name => 'Skill', :inverse_of => :creator
  has_many :user_skills
  has_many :skills, :through => :user_skills
end

class Skill < ActiveRecord::Base
  belongs_to :creator, :class_name => 'User', :inverse_of => :created_skills
  has_many :user_skills
  has_many :users, :through => :user_skills
end

class UserSkill < ActiveRecord::Base
  belongs_to :user
  belongs_to :skill
end

答案 1 :(得分:1)

拥有这两个模型

class User < ActiveRecord::Base 
   has_and_belongs_to_many :skills
 end

 class Skill < ActiveRecord::Base  
   has_and_belongs_to_many :users
 end

您必须创建额外的迁移(没有模型)

 rails generate migration CreateSkillsUsersJoin 

会给你

     class CreateSkillsUsersJoin < ActiveRecord::Migration
         def self.up
            create_table :skills_users, id => false do |t|
                t.references "user"
                t.references "skill"
             end
             add_index :skills_users,["user_id","skill_id"]
         end
         def self.down
            drop_table :skills_users
         end
      end

方法self.up和self.down你将添加它们

答案 2 :(得分:-1)

使用像acts_as_taggable_on这样的宝石可以很好地服务你,你可以在你的用户模型中简单地设置和使用它,例如:

acts_as_taggable_on :skills

老实说,他们已经把所有这些东西都搞清楚了,因为它并不像你想要做的那么简单,或者我应该重新说一下,然后说,你要做的就是过于“复杂”而且这个宝石允许你继续保持,在设置之后继续保持。

阅读自述文件。