My team and I developed several applications which required implementing publishing work flow/status transition (not ready, ready, published and archived) on lazily created models. You might think oh.. why not use acts_as_state_machine? We love acts_as_state_machine but we wanted something simple to handle just the publishing workflow and something that will cover the entire request life cycle (views, controller actions and model’s state transition). In other words we wanted a plugin that will require close to zero coding, literally, you just install the plugin and start publishing the models. With lot of hard work from my team we finally came up with the plugin “acts_as_publishable”. Yes using acts_as_publishable plugin, you can not only handle model’s state transition, but it also gives you views and a controller to handle all publishing actions and more. We are using acts_as_publishable plugin in several applications, including our own SimplifiedBills.com and LoudFeed.com.

We also set up a demo site here for you to play and see whether it is something that you would like to use in your projects.

Here is some a quick “howto”

1. Install the plugin using:

script/plugin install git://github.com/prabode/acts_as_publishable

2. Run the generator to create the plugin components.

./script/generate publishing

The above step will create the routes, views, controllers and tests.

3. Run the plugin tests using rake

cd RAILS_ROOT/vendor/plugins/acts_as_publishable
rake test

We have 34 tests and 104 assertions to cover all the functionality of the plugin.

4. Include acts_as_publishable in your model
Here is an example from our demo app:
class Document < ActiveRecord::Base
acts_as_publishable :status_column => "stage", :required_fields_for_publishing => ["name", "description"]
end

5. Optionally integrate i18n
Here is an example again from our demo app.
en.yml
en:
publishable:
document_name: "Name is required for publishing."
document_description: "Description is required for publishing."

6. Include “publishing_status_tag” tag in your views where you need the status and controls to appear.
Here is an example again from our demo app.

documents/show.html.erb

<%= publishing_actions_tag(@document)%>

Published At:

<%=h format_time(@document.published_at) %>

Archived At:

<%=h format_time(@document.archived_at) %>

Name:

<%=h @document.name %>

Description:

<%=h @document.description %>

<%= link_to ‘Edit’, edit_document_path(@document) %> |
<%= link_to ‘Back’, documents_path %>


documents/index.html.erb

<h1>Listing documents</h1>
<table border="0">
<tbody>
<tr>
<th>Status</th>
<th>Name</th>
<th>Published At</th>
<th>Archived At</th>
</tr>
<% @documents.each do |document| %>
<tr>
<td><%= publishing_status_tag(document, form_authenticity_token)%></td>
<td><%=h document.name %></td>
<td><%=h format_time(document.published_at) %></td>
<td><%=h format_time(document.archived_at) %></td>
<td><%= link_to 'Show', document %></td>
<td><%= link_to 'Edit', edit_document_path(document) %></td>
</tr>
<% end %>

</tbody></table>
<%= link_to 'New document', new_document_path %>

Ok now some pictures to explain the rest of the story:

1. Not Ready, Readiness messages generated by the plugin, click on not ready image to see messages.

not ready, readiness messages

2. Ready, if the document is ready, it will show the publish button
During publishing actions, acts_as_publishable will set the status, published_at or archived_at and update your model.

ready, publish button

3. Published, if the document is published, it will show the unpublish and archive buttons.

published, unpublish or archive button

4. Archived, if the document is archived, it will show the reset button to resurrect.

archived, reset button

We think we have a pretty good plugin, of course we are biased. Try it out and let us know what you think.