Introducing: The Social Welfare Rails Plugin

Social Welfare Overview
Social Welfare is a Rails plugin that makes it dead simple to update children objects from within their parent’s view. The plugin has been streamlined so that you don’t have to write much code to derive the benefits.
The problem with Rails is that it is hard to build interfaces that facilitate edits of multiple related items. Say for instance you have a shopping list and you want to modify the description of each item in the list. To do so with a scaffolded version of rails you would have to visit the edit URL of each item in the list! AJAX goes part of the way to solve this problem using in-place editing and so on, but ultimately this system falls short in situations like those that require atomic transactions.
What You Get

Social Welfare gives you the following features:
- Update a child element
- Add a new child
- Remove an existing child
- Sort the children
- Clone a child
All user updates are made to the interface only and no data is transmitted to the server until the user submits the form. The screenshot to the right is taken while updating a parent. The interface when creating a new parent is almost exactly the same (and so is the code).
How To Use Social Welfare
Here’s a very quick example of using the plugin. For full documentation check out the rdoc’s. Please note that you only need to edit parent models and views. There is no need to modify controller classes at all!
# model/todo_list include SocialWelfare has_many :items, :class_name => "TodoItem", :foreign_key => "todo_list_id", :subsidize => true, :order => 'sort_id'
# views/todo_list/new
<% form_for(@todo_list, :html => {:onsubmit => reorder_children(@todo_list, :items, 'sort_id')}) do |f| %>
<%= render :partial => 'list', :locals => {:f => f} %>
<%= f.submit "Update" %>
<% end %>
# views/todo_list/_list <b>Name</b> <%= f.text_field :name %> <% subsidize(@todo_list, :items, 'order' => 'sort_id') do |children| %> <table id="items"> <tr> <th></th> <th>sort id</th> <th>description</th> <th></th> </tr> <%= children.render 'hidden_elements' => false %> </table> <%= children.add %> <% end %>
# views/todo_list/_item
<tr class="<%= item.css_class %>">
<td>
<%= item.hidden_elements %>
<%= item.up %>
<%= item.down %>
</td>
<td><%= item.sort_id %></td>
<td>
<input type="text" name="<%= item.html_name('description') %>" value="<%= item.description %>" />
</td>
<td>
<%= item.remove %>
<%= item.clone %>
</td>
</tr>
<% end %>
How To Install
From the root of your rails application:
ruby script/plugin install http://dev.alexpooley.com/social_welfare/tags/1.0 rm -rf vendor/plugins/social_welfare mv vendor/plugins/1.0 vendor/plugins/social_welfare
If you want to run the todo demo application then you will find it in the test directory of the plugin. You will need to run “rake db:migrate” to build the database. The demo assumes you have sqlite3 setup for Rails. If this is not the case, you will need to modify the database configuration of the demo application.
More Details
Find out more about the plugin on the Social Welfare page.
Tags: rails, ruby, social welfare
December 18th, 2007 at 7:54 am
[...] Sub List Rails Plugin October 12th, 2007 My fixes to this plugin have been superseded by a plugin I wrote from scratch. I highly recommend you check it out. [...]
February 11th, 2008 at 8:13 pm
Great stuff, and perfect for my current needs.
My head explodes trying to reconcile the need for child.html_name (to work the child_attributes= assignment) and the standard FormHelpers expectation of model + attribute parameters, so I had to roll my selects by hand. No biggy :-)
Thanks for making this available.
February 12th, 2008 at 10:39 pm
Hi Alex,
Wow. Looking nice! Congrats.
October 30th, 2008 at 6:10 am
Good stuff.
A quick comment on has_many override [line 61] in social_welfare.rb. When you are determining the child class name, if no :class_name option is provided, the eval(nil) fails expecting a string for eval. You might want to add a nil check, so that it defaults to the camelize. Something like,
child_class = (eval(options[:class_name]) if options[:class_name]) || child_singular.camelize.constantize
October 30th, 2008 at 7:24 am
Thanks for the comment Raghu. I think the latest stable Rails (2.1) automagically handles all the has_many monkey patching I’ve performed with this plugin. I’ll have to look in to this a bit more deeply when I get the time.