Module InheritedResources::PolymorphicHelpers
In: lib/inherited_resources/polymorphic_helpers.rb

polymorphic associations

In some cases you have a resource that belongs to two different resources but not at the same time. For example, let‘s suppose you have File, Message and Task as resources and they are all commentable.

Polymorphic associations allows you to create just one controller that will deal with each case.

  class Comment < InheritedResources::Base
    belongs_to :file, :message, :task, :polymorphic => true
  end

Your routes should be something like:

  resources :files do
    resources :comments #=> /files/13/comments
  end
  resources :tasks do
    resources :comments #=> /tasks/17/comments
  end
  resources :messages do
    resources :comments #=> /messages/11/comments
  end

When using polymorphic associations, you get some free helpers:

  parent?         #=> true
  parent_type     #=> :task
  parent_class    #=> Task
  parent          #=> @task

This polymorphic controllers thing is a great idea by James Golick and he built it in resource_controller. Here is just a re-implementation.

optional polymorphic associations

Let‘s take another break from ProjectsController. Let‘s suppose we are building a store, which sell products.

On the website, we can show all products, but also products scoped to categories, brands, users. In this case case, the association is optional, and we deal with it in the following way:

  class ProductsController < InheritedResources::Base
    belongs_to :category, :brand, :user, :polymorphic => true, :optional => true
  end

This will handle all those urls properly:

  /products/1
  /categories/2/products/5
  /brands/10/products/3
  /user/13/products/11

nested polymorphic associations

You can have polymorphic associations with nested resources. Let‘s suppose that our File, Task and Message resources in the previous example belongs to a project.

This way we can have:

  class CommentsController < InheritedResources::Base
    belongs_to :project {
      belongs_to :file, :message, :task, :polymorphic => true
    }
  end

Or:

  class CommentsController < InheritedResources::Base
    nested_belongs_to :project
    nested_belongs_to :file, :message, :task, :polymorphic => true
  end

Choose the syntax that makes more sense to you. :)

Finally your routes should be something like:

  resources :projects do
    resources :files do
      resources :comments #=> /projects/1/files/13/comments
    end
    resources :tasks do
      resources :comments #=> /projects/1/tasks/17/comments
    end
    resources :messages do
      resources :comments #=> /projects/1/messages/11/comments
    end
  end

The helpers work in the same way as above.

Methods

Protected Instance methods

Returns the parent object. They are also available with the instance variable name: @task, @file, @note…

If the polymorphic association is optional, we might not have a parent.

Returns the parent type. A Comments class can have :task, :file, :note as parent types.

[Validate]