ActiveScaffold, Acts_as_taggable_on_steroids
Update: also read Active Scaffold + Acts_as_taggable + Auto Completion.
This is kind of an advanced topic, but I think it may be useful to a lot of people.
ActiveScaffold is a great plugin to start building a user interface. The great thing about AS is, that is automatically recognizes associated models. When editing a model, you can easily add or select another model that you want to associate with is.
The best example of this is an Article, where you can select the author (the associated User model) with a drop down box.
There is only one point where I ran into trouble with ActiveScaffold: acts_as_taggable_on_steroids.
Acts_as_taggable_on_steroids allows you to easily attach tags to models and do all kinds of crazy stuff with them. But, if you want to integrate in into AcitveScaffold, you’re in for a tough ride.
ActiveScaffold supports has_many :through associations, but not in a way that is compatible with acts_as_taggable_on_steroids. Let me show you.
In your ArticlesController you specify which columns to show. “tag_list” is a stringified version of the tags associated with the Article, which is great for showing to a user.
However, if you want to edit it an article (or create one), I don’t want a text field where I have to enter tags manually, all I want are a bunch of check boxes, so I can check which tags apply to this article.
Showing the check boxes is easy with AS. By default I show ‘tags’, only in the list view do I use ‘tag_list’ instead. Also, make sure to set the ui_type for the tags column to :select. This will show you check boxes, instead of a sub form that allows you to create tags manually.
active_scaffold :article do |config| config.columns = [:title, :body, :tags, :author, :created_at] config.list.columns = [:title, :author, :tag_list, :created_at] config.columns[:tags].ui_type = :select end
Well, very nice, right. You can now happily select the tags you want, and save your article. Not.
As you may have noticed, the tags are not saved. Why? Acts_as_taggable adds a ‘tags’ attribute to the model, however, when the Article model is saved, the tags attribute is overwritten by the tags specified in the “tags_list” attribute.
The only way to solve this is to convert the tags selected in AS and store them as the tags_list attribute for the Article.
First, let’s add a private method in the ArticleController class:
private def new_tag_list(tag_ids) tag_ids.map {|k,h| h['id']}.collect {|i| Tag.find(i)}.map do |tag| tag.name.include?(Tag.delimiter) ? "\"#{tag.name}\"" : tag.name end.join(Tag.delimiter.ends_with?(" ") ? Tag.delimiter : "#{Tag.delimiter} ") end
And add two protected methods that extend the functionality of ActiveScaffold:
protected def before_create_save(record) record.tag_list = new_tag_list(params[:record][:tags]) end def before_update_save(record) record.tag_list = new_tag_list(params[:record][:tags]) end
This will take the actual form values from AS and create a tags_list. This new tags_list is then assigned to the article (named ‘record’ here). The two protected methods process the tags every time an Article is created or updated.
With this in place, you can happily assign tags to your articles! Please let me know if it worked for you, or if you have made any improvements to this solution.









Hi,
i found your article very interesting, and i tried to reproduce what you did with AS…
But unfortunatly, it doesn t work for me…
I did the exact samething as you, but AS tell me “no option” in the Tags field….
i ll appreciate your help
Guillaume.
Guillaume: Did you create the proper tables for the tags?
Make sure you have the acts_as_taggable call in your model as well. Maybe restart your development server, that helps too sometimes. Let me know how it goes.
– You probably have the correct tables, but no tags are in it yet. You cannot currently add a new tag, hence the “no option” message. I’ll post a new article with more info on that later.
Ok, so actually i added manually in the DB one tag, and now it works, but something still weird in you article,
is’nt it possible to add manually tag ?
i mean having checkbox to choose the tags for your article is very cool, but if the right tag is’nt present, is there a way to show a text field where you can add tags to the artcile and by the way to the tag DB ?
Guillaume.
Yes, I know. I’m working on a solution for that. I’ll post it in a new article later this week, probably.
Ok, so far i m waiting for a genius solution from you….
thkx…
Any progress ?
thanks :)
Nope, not yet. I’m currently having exams and next tuesday I have to deliver a presentation to get my CS degree.
I’m trying different approaches now, but I think I have found something. Take a look at the _form_association views. That could be very useful.
I will… but i guess you ve got more knowledge that me on AS ans RoR…
Good luck for your exams
Hi,
Did you have any success of resolving the tag problem ?
(the problem that you can not add tags)
Thanks
Guillaume
[...] digg_url=’http://ariejan.net/2007/07/01/activescaffold-acts_as_taggable-auto-complete/’; digg_skin = ‘button’; digg_bgcolor = ‘#FFFFFF’; digg_title = ‘ActiveScaffold + acts_as_taggable + Auto Complete’; digg_bodytext = ”; digg_topic = ”; I’ve talked before on how to use ActiveScaffold with acts_as_taggable_on_steroids. [...]
I’ve just posted a new article describing a (quite different) solution to this problem.
Read it here: http://ariejan.net/2007/07/01/activescaffold-acts_as_taggable-auto-complete/
i have a question,how to short label in design with activescaffold????
so is there any possibility that this routine from above -
def new_tag_list(tag_ids)
tag_ids.map {|k,h| h['id']}.collect {|i| Tag.find(i)}.map do |tag|
tag.name.include?(Tag.delimiter) ? “\”#{tag.name}\”" : tag.name
end.join(Tag.delimiter.ends_with?(” “) ? Tag.delimiter : “#{Tag.delimiter} “)
end
- wouldn’t work in ruby 1.86 and rails 2.0.2? Or with acts_as_taggable_on_steroids (as of 30 March 2008)?
It throws a
NoMethodError (You have a nil object when you didn’t expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.map):
/app/controllers/recipes_controller.rb:46:in `new_new_tag_list’
/app/controllers/recipes_controller.rb:29:in `before_create_save’
/vendor/plugins/active_scaffold/lib/actions/create.rb:75:in `do_create’
when trying to create a new “recipe”. the tag table is not empty, I put a couple in by hand…
any ideas?
@Kristofer: I haven’t used this for a while. This probably has to do with acts_as_taggable_on_steroids. I’m not sure you need these helper methods anymore. Did you try using the ‘tag_list’ property directly? I think that should work now.
Yep. I took out the before_*_save routines and it works like a champe, even your autocomplete stuff works. Thanks!
I do have to say, even after working with Ruby for 9 months, your new_tag_list method made my head hurt trying to figure it out. I wasn’t able to – that’s why I finally wrote to ask you about it all.
How i can edit tags (rename, delete, add new) with activescaffold?
I try debug private methods:
protected
def before_create_save(record)
record.tag_list = new_tag_list(params[:record][:tags])
end
def before_update_save(record)
record.tag_list = new_tag_list(params[:record][:tags])
end
And i can`t =) Becouse this methods nt used when i try update tags.
Maybe its not work with rails 2.3.2 ?