2009-02-19 78 views
77

我正在努力让HATBM正常工作。我有一个殴打scanario:文章和标签。我认为,应该在这里使用HABTM,因为它是一种多对多的关系。 但是我不知道是否应该手动创建连接表(在这种情况下是articles_tags)。我是否需要手动为HABTM连接表创建迁移?

我目前的代码如下:

class Article < ActiveRecord::Base 
    has_and_belongs_to_many :tags 
end 

class Tag < ActiveRecord::Base 
    has_and_belongs_to_many :articles 
end 

当我运行迁移,则不会创建第三个表。 另外,我想补充一点,我的第三张表不承担任何域逻辑,只是盲目分配。

我用Rails 2.2.2

+1

即使在第四轨,我猜这个答案是......“是”? ( – dtc 2013-12-09 21:48:29

+1

@dtc,仍然是,仍然如此。 – Valentin 2013-12-10 06:34:23

回答

140

你应该在一个表的迁移做到这一点,或者在单独的迁移,如果这些移民已经跑:

create_table :articles_tags, :id => false do |t| 
    t.references :article, :tag 
end 

add_index :articles_tags, [:article_id, :tag_id] 

这将为你创建表格并且:id => false告诉Rails不要向这个表格添加一个id字段。还有一个索引,它将加快查找这个连接表。

你也可以生成此模型(ArticlesTag),并做到:

# article.rb 
has_many :articles_tags 
has_many :tags, :through => :articles_tags 

# tag.rb 
has_many :articles_tags 
has_many :articles, :through => :articles_tags 

# article_tag.rb 
belongs_to :tag 
belongs_to :article 

然后从script/generate model articles_tag调用生成的迁移创建表。

+0

感谢雷达,这就是我所需要的! – Valentin 2009-02-19 07:51:56

+12

有趣的是,官方指南或文档没有说明这一点,我不得不挖掘Stackoverflow。 – lzap 2011-03-07 08:14:41

7

您可能还需要添加索引的迁移:

add_index “articles_tags” 里, “article_id”

add_index “articles_tags”, “TAG_ID”

但是,如果你想标记功能我建议acts_as_taggable_on Rails插件:

http://www.intridea.com/tag/acts_as_taggable_on http://github.com/mbleigh/acts-as-taggable-on/

我已经在一个项目中使用过它,它很容易实现。

标记连接表的问题之一是它可以很容易地为您希望制作标记的每种内容类型(即comments_tags,posts_tags,images_tags等)创建连接表。这个插件使用一个标记表,其中包括一个鉴别器来确定内容类型,而不需要每种类型的特定连接表。

相关问题