Нужно ли вручную создавать миграцию для таблицы соединений HABTM?

Сейчас я боюсь, чтобы HATBM работал правильно. У меня есть избитый scanario: статьи и теги. Я полагаю, HABTM следует использовать здесь, так как это отношения "многие ко многим". Однако я не знаю, должен ли я вручную создать таблицу соединений (articles_tags в этом случае).

Мой код в настоящее время выглядит следующим образом:

class Article < ActiveRecord::Base
  has_and_belongs_to_many :tags  
end

class Tag < ActiveRecord::Base
  has_and_belongs_to_many :articles
end

Когда я запускаю миграцию, не создается 3-я таблица. Кроме того, я хотел бы добавить, что моя третья таблица не несет никакой логики домена, просто слепое назначение.

Я использую Rails 2.2.2

Ответ 1

Вы должны сделать это при миграции одной из таблиц или в отдельной миграции, если эти миграции были выполнены:

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.

Ответ 3

Вероятно, вы также захотите добавить индекс к миграции:

add_index "articles_tags", "article_id"

add_index "articles_tags", "tag_id"

Однако, если вы хотите использовать функцию тегов, я бы рекомендовал плагин actions_as_taggable_on rails:

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

Я использовал его в проекте, и его было очень легко реализовать.

Одна из проблем с таблицей соединений для тегов заключается в том, что она может легко получить уродливое создание таблицы соединений для каждого типа контента, который вы хотите сделать taggable (т.е. comments_tags, posts_tags, images_tags и т.д.). Этот плагин использует таблицу тегов, которая включает дискриминатор для определения типа содержимого без необходимости конкретной таблицы соединений для каждого типа.