Or little computing tricks and hacks
Rails: Create a HABTM association between categories and articles
March 4, 2015Posted by on
While looking to migrate the legacy database from WordPress into my Rails app, I noticed that one of the specs for the database was wrong. An article IS allowed more than one category. Sigh! That part of the implementation was ready. After studying the different possibilities, I opted for having a join table. This is what I did:
rails g controller Categories create edit rails g model Category name:string
and all what is needed in Rails for the new model.
Then I added the following to the newly created Category model:
class Category < ActiveRecord::Base has_and_belongs_to_many :articles end
and to the preexisting Article model:
class Article < ActiveRecord::Base has_and_belongs_to_many :categories end
Having this, I have to create the join table, whose migration is as follows:
class CreateCategoriesAndArticles < ActiveRecord::Migration def change create_table
:categories_articles, id: false do |t| t.belongs_to :category, index: true t.belongs_to :article, index: true end end end
Two things to note:
- The name of the table is crucial, otherwise the magic to access the categories of an article will not work.
id: falsetells the database manager to create a table without an indexable id.
If you create the table with the wrong name as I did, here is the migration to rename a table (taken from Stack overflow):
class RenameOldTableToNewTable< ActiveRecord:Migration def change rename_table :old_table_name, :new_table_name end end
Once created, the output in
as described in as described here is:
development=# select column_name from information_schema.columns where table_name='categories_articles'; column_name ---------------- article_id category_id (2 rows)
To access the categories in an article, the magic I mentioned before, do:
which will return an array of the category ids associated with that article.
By the way, this is a HABTM association, Has And Belongs to Many. This association is done in the table pairing the two ids.
In this post I wrote about providing the option of selecting one or more categories for an article.