NoobOnRails

Ruby on Rails tips, tricks and hints for the aspiring rails hero.



Friday, November 18, 2005

Using acts_as_taggable in Rails (for the uber noobie)


If you're up on web trends, you know how cool having the ability to tag items on your site makes you look. Cool enough to wear shades in doors. You'll be glad to know that, true to the Ruby and Rails way of keeping things simple, adding tag finctionality isn't too bad. Dema wrote up a little mixin called acts_as_taggable which makes tagging in rails a lot eaiser to do. It started out as a mixin but it's now a gem so installing it is a snap, just run this from a command prompt (from inside your app folder, you don't have to do this now)...

gem install acts_as_taggable

and you're off and running.

Let start with a brand new app. Inside the folder of your choice, run...

rails books

...to get the app's basic structure laid out. After Rails creates the structure and it's all laid out, pop over into your ...\Book\app\config\ folder and edit your database.yml file. Were going to be doing all of our work in development mode so you need to only work with the development section. Edit it to fit your environment. I'll be using MySql so my development definition looks like this:


development:
adapter: mysql
database: books_development
username: root
password: root
socket: /path/to/your/mysql.sock


In your books_development database, we're also going to .


CREATE TABLE `books` (
`id` int(6) unsigned NOT NULL auto_increment,
`title` varchar(50) NOT NULL default '',
`author` varchar(50) NOT NULL default '',
`description` text NOT NULL,
`created_on` datetime NOT NULL default '0000-00-00 00:00:00',
`updated_on` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `tags` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(30) NOT NULL default '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;


CREATE TABLE `tags_books` (
`tag_id` int(11) NOT NULL default '0',
`book_id` int(11) NOT NULL default '0'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Copy this into a text file and save it with a .sql extension and import it into your book_development database. If you need help on that, open the MySql command line client and type in \h for help.

Now our database structure exists so lets do some scaffolding since it's so easy. From inside your app directory (for this case, in the Book folder) from a command prompt just run

ruby script\generate scaffold Book

At this point, you could go ahead and run...

gem install acts_as_taggable

...inside your app folder to install the required gem. As far as I can tell, you'll have to do this for each app you want to use this gem in. After that's done, let's test it and make sure everything is up and running. Start webrick (run ruby script\server from inside your app folder) and take a look at your site. My url was http://localhost:3000/books, yours should be something simliar. Go ahead and create some books to make sure everything is working so far.

After you have some data and you're chomping at the bit to get to tagging, add (manually type it in, don't copy and paste it from here)

require_gem 'acts_as_taggable'

...right above the end in your environment.rb (in your books\config\ folder). Since we edited the emvironment/rd file, you'll need to ctrl+c your webrick instance (on Windows) to stop it and then bring it back up. Now you need to create a Tag model. Running...

ruby script\generate model Tag

...will do. You don't need to anything in it yet, but it needs to exist for this to work. Next, hop over to your book model and add

acts_as_taggable

We're getting closer. You now need to pop into your books_controller and save the tags params inyour database. Open your books controller and look at the create method. More specifically, the first few lines...

@book = Book.new(params[:book])
if @book.save
flash[:notice] = 'Book was successfully created.'

You're probably thinking (at least I know I did), shouldn't the Book.new(params[:book]) be gathering all the data from the form? The problem is, the join table we created (tags_books) links the book id to the tag id, how can they be linked if the book.id doesn't exist yet? They can't, so you need to @book.save first so that the book record can be created and be assigned a book.id. Then you can save the tags. So instead of the above, it needs to look like this...

@book = Book.new(params[:book])
if @book.save
@book.tag(params[:tags])
flash[:notice] = 'Book was successfully created.'


...that should do it. Now or models are ready and our controller is ready. Now we need to work on that view. Let's start with the _form.rhtml partial in your app\views\books\ folder. Both the new.rhtml and edit.rhtml point to this partial but we won't worry about how to edit them just yet. Right now, we just want to be able to add a new book with some tags. To do so, edit your _form.rhtml partial to look like this...





...you can stick that "tags for this book" line wherever you want in this partial and you should be good. Refresh and take a look at your http://localhost:3000/books/new page to see the new field. Test it out and create a new book with a tag or two. To enter in more than one tag, just add a space between them. After you save your tagged up book, you'll notice that it'll get created successfully and the data ends up in your database, but no tags show up on your list page. Time to tackle the list.rhtml view. Open that up and edit it so it looks like this...




...the book.tag_names.join(" ") is the code that pulls our tags out of the database, use a space to seperate them. Congrats, you know have some basica tag functionality going on. Check out Tagging on Steriods with Rails , the acts_as_taggable rdoc documentation as well as the actual rubyforge page for more info. I'll also put up a post with just the steps listed so you have an easy refernece point to refer back to without having to read this whole post again.



1 Comments:

  • At 3:50 AM, Anonymous Anonymous said…

    nice tutorial, works great.

     

Post a Comment

<< Home