Associated List - A little "has many" widget for rails

Posted by Craig Ambrose on October 09, 2006 at 02:07 AM

Ok, so I know that I’m not the first person to ever take a stab at a form widget for use in selecting multiple foreign key model objects, but I had a use for this in a project, and perhaps some of you will as well.

If you are producing a form for a rails model object and it has a “has_many” or “has_and_belongs_to_many” relationship of some other simple objects (which can be identified by name), then this plugin might be for you. It uses a select box to add items to the list, and delete buttons to remove them. It’s all client side, using hidden fields, until you submit the form and it saves the relationships in your model.

Don’t listen to me rambling, if you’re interested, Click Here to go look at the demo, then come back and read the rest.

Installing


script/plugin install svn://rubyforge.org/var/svn/ambroseplugins/associated_list

If you install with the rails plugin systems, then it will copy a associated_list.css file into your stylesheets directory. If it’s not there, or you install via some other method, or you’re updating, then do this:


cd vendor/plugins/associated_list/
rake update_scripts

And finally, make sure you include that stylesheet in your layout:


<%= stylesheet_link_tag 'associated_list' %>

Usage

If you have a model @widget of class Widget, that has_and_belongs_to_many :categories, then you simply use the form helper as follows (ie: the same as all the other helpers):


<%= associated_list 'widget', 'categories' %>

When the form is saved, params‘widget’ will contain an array of strings representing integer ids of the categories. Note: This will include one empty string object. This is to ensure that empty lists get saved, just ignore it.

Now, since your model object has a categories= method, but no category_ids= method, you’ll have to create one (in category.rb):


def category_ids=(category_id_array)
self.categories = category_id_array.reject{ |category_id| category_id == '' }.collect { |category_id| WidgetCategory.find(category_id.to_i) }
end

Not how I’m rejecting that empty string. Everything else is pretty straight forward. Really the plugin should extend the rails association helpers to add this method. If anyone wants to code that for me, drop me a line and I’ll patch it into the plugin.

Credits

This plugin was factored out of my railsday project, and so appart from some cleanup work and plugin-ification, it was coded by myself, Nigel Thorne and Simon Hildebrandt. If you use this plugin, please consider them to rock just as thoroughly as I do. :)

Post continues, click to read more...

Comments: 12 (view/add your own) Tags: (none)