| Path: | README |
| Last Update: | Mon Jan 07 12:10:06 +0900 2008 |
Social Welfare provides an easy method to save children objects via the parent. You probably only want to interact with the SocialWelfareHelper module, and the SocialWelfareHelper::ChildrenHelper and SocialWelfareHelper::ChildHelper classes.
Your use of this plugin starts with the SocialWelfareHelper#subsidize method.
The inner workings of this plugin are based on the railscast available at railscasts.com/episodes/75
| Author: | Alex Pooley (ampooley@gmail.com) |
| Copyright: | Copyright (c) 2007 Alex Pooley |
| License: | Distributes under the same terms as Ruby |
The Social Welfare plugin comes with a simple todo list application example. Here‘s a very quick run through of the important bits in the todo list application. Don‘t fret if you get a bit lost, you can find the full working example in the test directory of the plugin.
Include the SocialWelfare plugin in any parent models that are going to contain children. Then add ":subsidize => true" to any has_many relationships that you would like to subsidize.
# models/todo_list
include SocialWelfare
has_many :items, :class_name => "TodoItem", :foreign_key => "todo_list_id", :subsidize => true, :order => 'sort_id'
module TodoListsHelper
include SocialWelfareHelper
end
Make sure you include prototype in the HEAD part of the view.
# views/layouts/todo_list.html.erb
<%= javascript_include_tag :defaults %>
If you want to reorder the children then add a call to reorder_children to the form in your parent.
# views/todo_list/new.html.erb
<% form_for(@todo_list, :html => {:onsubmit => reorder_children(@todo_list, :items, 'sort_id')}) do |f| %>
<%= render :partial => 'list', :locals => {:f => f} %>
<p>
<%= f.submit "Update" %>
</p>
<% end %>
This code updates the order of the list when the user presses the submit button. Note that my new and edit parent form views look exactly the same except for the text of the submit button.
Add a call to "subsidize" at the point you want to start displaying the children. The subsidize method yields a helper that you can use to render the parents children, and also an ‘Add child’ button.
# views/todo_list/_list.html.erb
<p>
<b>Name</b><br />
<%= f.text_field :name %>
</p>
<% 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 %>
The "children.render" call renders a partial for each child. The name of the partial defaults to the singular version of the accessor defined in subsidize. The "’hidden_elements’ => false" call prevents the render method from prefixing each child with hidden elements required for this plugin to work. If the hidden_elements are suppressed, they must be output manually within the child partial.
The children are rendered using the partial below. You can access the child as a normal ActiveRecord object (as ‘item’ in the example). However, the object also has the ability to add ‘up’ and ‘down’ buttons to move itself up and down the list, as well as ‘remove’ and ‘clone’ buttons. These buttons can be customized with different text or images by passing a string as the first argument to the method. You must wrap the child in a HTML element, and attach a class to that element by calling css_class on the local variable passed to the partial.
# views/todo_items/_todo_item.html.erb
<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>
Also, it‘s possible to re-use the partial in other forms, even when the partial is not subsidized. All the method decorations such as remove/up/down/clone/css_class return nil when subsidize does not exist. So for instance, you can have a views/todo_items/new.html.erb with a form that renders the views/todo_items/_todo_item.html.erb partial. Keeping it DRY. Nifty hey ;)
One important point is that I have not managed to get the plugin to work with Rails form field helpers such as text_field, text_area, etc. However, this is a minor, and hopefully temporary inconvenience.
For now, nesting subsidize calls does not work. This appears to be a Rails bug which is under investigation.