Polymorphic Associations in Rails3

ror31
Social sharing

ror31In polymorphic associations, a model can belong to more than one model, on a single association.

Here is an example where a model is associated with two other models in Rails3. For example we have Events and Article model which have comments. So the “Comment” model is common between the “Event” and “Article” model. Here are the steps to implement the polymorphic association between these three models.

Step#1
Let’s create a resource “Comment” by rails generator.

rails g scaffold Comment content:text

Step#2

Add associations in the models as below

Comment model:

class Comment < ActiveRecord::Base
attr_accessible :commentable_id, :commentable_type, :content
belongs_to :commentable, :polymorphic => true  #Now, it is acted as polymorphic
end

Event model:

class Event < ActiveRecord::Base
attr_accessible :name
has_many :comments, :as => :commentable
end

Article model:

class Article < ActiveRecord::Base
attr_accessible :name
has_many :comments, :as => :commentable
end

Step#3

Add the following attributes in the migration files of the comment model

Look for newly created file under “db/migrate” folder

class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.text :content
t.references :commentable, :polymorphic => true
t.timestamps
end
end
end

Then execute rake db: migrate in the command line

Step#4

Add nested resources inside the “config/routes.rb” file

resources :events  do
resources :comments
end
resources :articles do
resources :comments
end

Step#5

Add link to add new comments in view page of article and events as follows

In “/app/views/events/show.html.erb”

<%= link_to 'New comment', new_event_comment_path(@event)  %>

In /app/views/articles/show.html.erb

<%= link_to 'New comment', new_article_comment_path(@article)  %>

Step#6

Changing the form_for tag in new comment page

In “/app/views/comments/_form.html.erb”

Before

<%= form_for (@comment) do |f| %>

After

<%= form_for [@commentable, @comment] do |f| %>

Add following codes in both “Articles” & “Events” controllers to get the comments individually

In “/app/controllers/events_controller.rb”

def show
@event = Event.find(params[:id])
@comments= @event.comments #added to view all the comments for the selected event
respond_to do |format|
format.html # show.html.erb
format.json { render json: @event }
end
end

In “/app/controllers/articles_controller.rb”

def show
@article = Article.find(params[:id])
@comments= @article.comments #added to view all the comments for the selected article
respond_to do |format|
format.html # show.html.erb
format.json { render json: @article }
end
end

Step#8

Add the following codes to “Comments” controller to creating a comment

In “/app/controllers/comments_controller.rb”

class CommentsController < ApplicationController
def new
@commentable = find_commentable
@comment = Comment.new
end
def create
@commentable = find_commentable
@comment = @commentable.comments.build(params[:comment])
if @comment.save
flash[:notice] = "Successfully created comment."
redirect_to :id => nil
else
render :action => 'new'
end
end
 
private
 
def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
end

Now the comment model will work as a polymorphic association between article and event model.

Summary
Article Name
Polymorphic Associations in Rails3
Description
In polymorphic associations, a model can belong to more than one model, on a single association.
Author
Publisher Name
Andolasoft

Your recently viewed posts:

    Contact Us

    We’d love to help & work with you




    When do you want to start ?


    Enter your email address to stay up to date with the latest news.
    Holler Box

    Orange Exit pop up

    Subscribe for the latest
    trends in web and
    mobile app development
    Holler Box

    Exit pop up

    Sad to see you leaving early...

    From "Aha" to "Oh shit" we are sharing everything on our journey.
    Enter your email address to stay up to date with the latest news.
    Holler Box