If you're building an ecommerce website that sells a number of different kinds of goods, you might want to institute tagging. This mainstay of many Internet sites makes it easier to categorize items, and can assist your visitors in finding what they're looking for. This four-part article series shows you how to add tagging support to your site using Ruby on Rails. This article is excerpted from chapter seven of the book Practical Rails Projects, written by Eldon Alameda (Apress; ISBN: 1590597818).
Tagging Support - Setting Up for Tagging (Page 4 of 4 )
As in previous chapters, we will use ActiveRecord migrations to modify the database schema to implement tagging. We will add tables, create a model, and develop unit tests. We’ll also introduce testing with the console.
Updating the Database Schema
When George assigns a set of tags to a book, we must be able to store them somewhere, and also be able to associate them with the book. For this purpose, we will add two new tables to the database schema (see Figure 7-1):
Thetagstable is where the uniqueidandnameof all tags are stored.
Thebooks_tagstable is used to associate a set of tags with one or more books, through a many-to-many relationship (ActiveRecord database relationships are covered in Chapter 3). Thebooks_tagstable includes foreign key references to thetagsandbookstables.
Figure 7-1.Tables used by the tagging system
Next, create the migration by executing thegeneratecommand:
Thegeneratescript creates an empty migration script for you. Next, change the script as shown in Listing 7-1.
Listing 7-1. Migration Script for the Tagging Functionality
class CreateTagsAndBooksTags < ActiveRecord::Migration def self.up create_table :tags do |table| table.column :name, :string, :limit => 255, :null => false, :unique => true end
create_table :books_tags, :id => false do |table| table.column :tag_id, :integer, :null => false table.column :book_id, :integer, :null => false end
say_with_time 'Adding foreign keys' do # Add foreign key reference to books_tags table execute 'ALTER TABLE books_tags ADD CONSTRAINT fk_tb_tags➥ FOREIGN KEY ( tag_id ) REFERENCES tags( id ) ON DELETE CASCADE' execute 'ALTER TABLE books_tags ADD CONSTRAINT fk_tb_books➥ FOREIGN KEY ( book_id ) REFERENCES books( id ) ON DELETE CASCADE' end say_with_time 'Adding default tags' do execute(insert_tags_sql) end end
def self.down drop_table :books_tags drop_table :tags end
def self.insert_tags_sql <<-END_OF_DATA insert into tags values (1,"Romance"), (2,"Cooking"), (3,"Mystery"), (4,"History"), (5,"Politics"), (6,"Elvis"), (7,"Science Fiction") END_OF_DATA end end
The script creates the two tables,tagsandbooks_tags.The migration also adds foreign key references to thebooks andtagstables by executing raw SQL with theexecutecommand. At the end of the migration, the script adds a default set of tags to thetagstable by again calling theexecutecommand.
Note Thecreate_tablemethod creates anidcolumn by default. When creating thebooks_tagsjoin table, we are telling thecreate_tablecommand not to add anidcolumn by setting theidparameter tofalse.
Now, run the migrations by executing the following command:
You should see the command run without errors.
Note Remember to clone the database structure from the development to the test database by executingrake db:test:clone_structure. You can also perform the migration by executing therakecommand without parameters. This will run the tests and the migrations.
Please check back tomorrow for the second part of this series.
DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.