README.md

Deprecation notice

Since Rails 3 came out, I have no longer used Inherited Resources and it is no
longer actively maintained. I have found that the responders abstraction
offers the perfect balance between hiding and showing too much logic in controllers.
That said, I suggest developers to make use of Rails' respond_with feature
alongside the responders gem as a
replacement to Inherited Resources.

Inherited Resources

Inherited Resources speeds up development by making your controllers inherit
all restful actions so you just have to focus on what is important. It makes
your controllers more powerful and cleaner at the same time.

In addition to making your controllers follow a pattern, it helps you to write better
code by following fat models and skinny controllers convention. There are
two screencasts available besides this README:

Responders

Since Inherited Resources 1.0, responders are not part of its core anymore,
but is set as Inherited Resources dependency and it's used by default by
InheritedResources controllers. Be sure to check the documentation to see
how it will change your application:

Using responders will set the flash message to :notice and :alert. You can change
that through the following configuration value:

InheritedResources.flash_keys = [ :success, :failure ]

Notice the CollectionResponder won't work with InheritedResources, as
InheritedResources hardcodes the redirect path based on the current scope (like
belongs to, polymorphic associations, etc).

Basic Usage

To use Inherited Resources you just have to inherit (duh) it:

classProjectsController < InheritedResources::Baseend

And all actions are defined and working, check it! Your projects collection
(in the index action) is still available in the instance variable @projects
and your project resource (all other actions) is available as @project.

For each request, it first checks if the "controller/action.format" file is
available (for example "projects/create.xml") and if it's not, it checks if
the resource respond to :to_format (in this case, :to_xml). Otherwise returns 404.

Another option is to specify which actions the controller will inherit from
the InheritedResources::Base:

As you might expect, collection (@projects instance variable) is only available
on index actions.

If for some reason you cannot inherit from InheritedResources::Base, you can
call inherit_resources in your controller class scope:

classAccountsController < ApplicationController
inherit_resources
end

One reason to use the inherit_resources macro would be to ensure that your controller
never responds with the html mime-type. InheritedResources::Base already
responds to :html, and the respond_to macro is strictly additive.
Therefore, if you want to create a controller that, for example, responds ONLY via :js,
you will have to write it this way:

In the case above, in your views you will have @users and @user variables, but
the routes used will still be accounts_url and account_url. If you plan also to
change the routes, you can use :route_collection_name and :route_instance_name.

Namespaced controllers work out of the box, but if you need to specify a
different route prefix you can do the following:

Then your named routes will be: admin_people_url, admin_person_url instead
of administrators_people_url and administrators_person_url.

If you want to customize how resources are retrieved you can overwrite
collection and resource methods. The first is called on index action and the
second on all other actions. Let's suppose you want to add pagination to your
projects collection:

The end_of_association_chain returns your resource after nesting all associations
and scopes (more about this below).

InheritedResources also introduces another method called begin_of_association_chain.
It's mostly used when you want to create resources based on the @current_user and
you have urls like "account/projects". In such cases you have to do
@current_user.projects.find or @current_user.projects.build in your actions.

You are opening your action and giving the parent action a new behavior. On
the other hand, I have to agree that calling super is not very readable. That's
why all methods have aliases. So this is equivalent:

Before we finish this topic, we should talk about one more thing: "success/failure
blocks". Let's suppose that when we update our project, in case of failure, we
want to redirect to the project url instead of re-rendering the edit template.

Much better! So explaining everything: when you give a block which expects one
argument it will be executed in both scenarios: success and failure. But if you
give a block that expects two arguments, the first will be executed only in
success scenarios and the second in failure scenarios. You keep everything
clean and organized inside the same action.

Smart redirects

Although the syntax above is a nice shortcut, you won't need to do it frequently
because (since version 1.2) Inherited Resources has smart redirects. Redirects
in actions calculates depending on the existent controller methods.

Redirects in create and update actions calculates in the following order: resource_url,
collection_url, parent_url (which we are going to see later), and root_url. Redirect
in destroy action calculate in following order collection_url, parent_url, root_url.

Success and failure scenarios on destroy

The destroy action can also fail, this usually happens when you have a
before_destroy callback in your model which returns false. However, in
order to tell InheritedResources that it really failed, you need to add
errors to your model. So your before_destroy callback on the model should
be something like this:

Belongs to

belongs_to accepts several options to be able to configure the association.
For example, if you want urls like "/projects/:project_title/tasks", you can
customize how InheritedResources find your projects:

Nested belongs to

Now, our Tasks get some Comments and you need to nest even deeper. Good
practices says that you should never nest more than two resources, but sometimes
you have to for security reasons. So this is an example of how you can do it:

This code creates delete and search actions in controller (they behaves like show and
index actions accordingly). Also, it will produce delete_resource_{path,url} and
search_resources_{path,url} url helpers.

What about views?

Sometimes just DRYing up the controllers is not enough. If you need to DRY up your views,
check this Wiki page:

Some DSL

For those DSL lovers, InheritedResources won't leave you alone. You can overwrite
your success/failure blocks straight from your class binding. For it, you just
need to add a DSL module to your application controller:

Remember that if your field is sent by client to server as an array, you have to write :permitted_field => [], not just :permitted_field.

Note that this doesn't work if you use strong_parameters' require method
instead of permit, because whereas permit returns the entire sanitized
parameter hash, require returns only the sanitized params below the parameter
you required.