Чи потрібно вручну створювати міграцію для таблиці приєднання HABTM?


77

Зараз я намагаюся, щоб HATBM працював правильно. У мене є побитий сканар: статті та теги. Я припускаю, що тут слід використовувати 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
Навіть на рейках 4 я здогадуюсь, що відповідь на це .... "так"? :(
dtc

1
@dtc, все ще так, все ще правда.
Валентин Васильєв

Відповіді:


141

Ви повинні зробити це під час міграції однієї з таблиць або в окремій міграції, якщо ці міграції були запущені:

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

add_index :articles_tags, [:article_id, :tag_id]

Це створить таблицю для вас і :id => falseповідомляє Rails не додавати поле ідентифікатора до цієї таблиці. Також є індекс, який прискорить пошук цієї таблиці об’єднань.

Ви також можете створити модель (ArticleTag) для цього і зробити:

# 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виклику.


Дякую, Радар, ось що мені потрібно!
Валентин Васильєв

12
Забавно, що в офіційних довідниках чи документації цього не зазначено. Мені довелося копати на Stackoverflow. Тай
lzap

Що, якби ви хотіли зв’язати їх з унікальною назвою для об’єднання, оскільки це об’єднання вже використовувалось.
Поїздка

Я думаю, вам слід додати індекси до таблиці приєднання, додавши add_index :articles_tags, [:article_id, :tag_id]до кінця changeметоду
Джованні Каппеллотто

Чи не повинно бути: article_tag (однина) у моделі?
Benjineer

8

1
Хоча про це слід десь згадувати в путівнику.
sholsinger 15.03.11

Прочитайте ці кілька рядків в API, щоб зрозуміти очікуване ім’я таблиці (наприклад, коли використовується той самий префікс). Це пояснить коментар @Giovanni.
Hugo Logmans

7

Можливо, ви також хочете додати індекс до міграції:

add_index "article_tags", "article_id"

add_index "article_tags", "tag_id"

Однак, якщо вам потрібна функція тегування, я рекомендую плагін act_as_taggable_on rails:

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

Я використовував його у проекті, і його було дуже легко здійснити.

Однією з проблем таблиці об’єднання для позначення є те, що вона може легко стати некрасивою, створюючи таблицю об’єднання для кожного типу вмісту, який ви хочете зробити позначуваним (тобто коментарі_теги, теги_тегів, зображення_тегів тощо). Цей плагін використовує таблицю міток, яка включає дискримінатор для визначення типу вмісту без необхідності певної таблиці об’єднання для кожного типу.


Посилання на методи міграції (або належать_то) автоматично додає індекси. Вам це не потрібно. Ви можете порушити міграцію за допомогою нього.
lzap

Посилання на методи міграції (або належать_то) насправді не додають автоматично індекси. (Думали, що вони це роблять :-)
lzap

IMHO було б краще створити складений первинний ключ. Але це специфічно для бази даних.
Арт Шайдеров,

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.