Automatically do the right thing with nested resources.
Ruby
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib
tasks
test
MIT-LICENSE
README.rdoc
Rakefile
init.rb
install.rb
uninstall.rb

README.rdoc

automatic_resources

Anyone who's had to deal with nested resources knows that it can get really messy to have to make everything conditional to support them. Basically it's just a pain in the ass. If you want to support a nesting structure like the one in the example below you'll be looking at a big tangled bowl of spaghetti in no time.

Automatic Resources saves you the trouble. It dynamically defines finder methods in your controllers and helpers as well as simple named urls that are 100% compatible with the standard ones but produce beautiful nested resource urls just like you should expect them to.

Compatible

Automatic Resources doesn't delve into Rails internals or do anything your grandmother would disapprove of. You can expect it to keep on keepin' on.

Example

map.resources :blogs do |blog|
  blog.resources :categories, :has_many => [:posts]
  blog.resources :posts
end

class PostsController < ApplicationController
  automatic_resources :blog, :category, :post

  # Add a prepend_before_filter that ensures that the blog resource exists, otherwise
  # call +record_not_found+
  require_resource :blog, :filter_method => :prepend_before_filter

  # This resource is required to be valid if it is in the url, otherwise it
  # is not required. Defaults to using the before_filter if :filter_method is
  # not specified.
  sometimes_require_resource :category

  # All other options are passed on to the selected filter method.
  require_resource :post, :only => [:show, :update]

  # Normal filter methods are created and used so they can be handled in the
  # usual way:
  skip_before_filter :sometimes_require_category_filter

  def show
    # blog, category, post methods are generated and available as helpers
    @blog_name = blog.name if blog?
    @category_name = category.name if category?
    @title = post.title

    # blogs, categories, posts collection methods as well:
    @category_names = categories.map(&:name) if category?
    @post_dates = posts.map(&:created_on)

    # Passing a collection method false for the execute parameter returns the
    # correctly scoped collection object without executing find(:all), which
    # allows you to apply other operations instead:
    @blog_count = blogs(false).count
  end

  def new
    # parent is automatically determined as either blog or category depending
    # on the route we used to get here.
    @post = build_post
  end

  def update
    if post.update_attributes(params[:post])
      flash[:notice] = 'Item was successfully updated.'
      # The correctly nested path will be produced automatially without
      # explicitly specifying it:
      redirect_to(post) 
    else
      render :action => "edit" 
    end
  end
end

<% form_for(item) do |f| %>
  Name: <%= f.text_field :name %>
<% end %>
<%= link_to 'Show', item %> |
<%= link_to 'Back', items_path %>

License

Copyright © 2009 Darrick Wiebe, released under the MIT license