devroom.io/drafts/2006-10-13-tagging-in-ajax_scaffold.md

71 lines
3.3 KiB
Markdown
Raw Normal View History

2013-03-22 22:53:57 +00:00
---
title: "Tagging in ajax_scaffold"
kind: article
slug: tagging-in-ajax_scaffold
created_at: 2006-10-13
tags:
- General
- Everything
- Web Development
- RubyOnRails
- Features
---
I've been using the <a href="http://www.ajaxscaffold.com/">Ajax Scaffold</a> for quite some time now. It's a great piece of software by <a href="http://www.height1percent.com/">Mr. Richard White</a> for <a href="http://www.rubyonrails.com">Ruby on Rails</a>. It seems that the plugin version of AS is getting quite a bit more attention than the generator. I started out with the generator but quickly reverted to the plugin since it's way more flexible and easier to use.
Since I wanted to create a quick app to inventory my CD/DVD collection (which is now in a very sexy alu DJ case) I used Ajax Scaffold to get me started. In the spirit of Web 2.0 I wanted to add tags to every CD so it would be easier to find certain kinds of disks later on. So, I added <a href="http://wiki.rubyonrails.org/rails/pages/Acts+As+Taggable+Plugin">acts_as_taggable</a>.
Acts_as_taggable basically allows you to tag any model in your app. So, I made my Disk model taggable. Great. Now I could do this:
:::ruby
d = Disk.new(:number => 1, :name => "Mac OS X 10.4.6 Install DVD 1")
d.tag_with("macoxs apple macbook install")
d.save
The real problem was, how to get this functionality easily integerated in Ajax Scaffold?
~
First of all I had to show a column in AS that included the tags attached to a given disk. I specify all rows manually in the Manager controller. Manager is scaffolded using AS. Here's what my Manager controller looks like:
:::ruby
class ManagerController < ApplicationController
ajax_scaffold :disk
@@scaffold_columns = [
AjaxScaffold::ScaffoldColumn.new(Disk, { :name => "number" }),
AjaxScaffold::ScaffoldColumn.new(Disk, { :name => "name" }),
AjaxScaffold::ScaffoldColumn.new(Disk, { :name => "tags",
:eval => "row.tag_list", :sort => "tag_list"}),
]
end
This will show three columns, including a column named 'tags'. Every model that acts_as_taggable has some extra methods. tag_list is a single string containing all tags seperated by spaces. So, the tags column shows the tag_list for that row. With :sort I specify that AS can just sort keywords alphabetically.
Great! I now can see tags on disks! But, we also need to add those tags and that's where it got tricky.
<h4>Adding tags</h4>
Adding tags is not done by assignment but by calling a method with your tags, as shown before: tag_with (string). I could create a custom create and update method for the Disks, but there's a prettier solution available.
tag_list returns a string with the current tags. How about using that same name to assign tags? It's rather easy. Here's my Disk model:
:::ruby
class Disk < ActiveRecord::Base
acts_as_taggable
validates_presence_of :name, :number
def tag_list=(new_tags)
tag_with new_tags
end
end
Now we can assign tags to tag_list as well as read the tags out. Now the only step is to add a special textfield to the form partial for AS.
:::rhtml
<label class="required">Tags</label>
<%= text_field 'disk', 'tag_list' %>
Now when a new disk is created or when one is updated, the tag_list will automagically be updated in a correct fashion.
Enjoy!