Skip to content

Instantly share code, notes, and snippets.

@spencereldred
Last active August 29, 2015 13:56
Show Gist options
  • Save spencereldred/8947250 to your computer and use it in GitHub Desktop.
Save spencereldred/8947250 to your computer and use it in GitHub Desktop.
polymormic assiciations

Polymorphic Association

When you have one model that could belong to any one of a set of models.

Comments is the classic example.

A comments could belong to a book, a video or a photo.


Goals:

  • Understand overview of polymorphic relationships.

  • How to set up model relationships.

    *

    comment.rb: "belongs_to :commentable, polymorphic: true"

    *

    book.rb: "has_many :comments, as: :commentable, dependent: :destroy"

  • How to set up the migration file.

    *

    commentable_id:integer, commentable_type:string

  • How to use the active record relationship commands.

    *

    book.comments => finds all comments for a book

    *

    comment.commentable => to find model type for a comment

    *

    book.destroy => deletes book and all associated comments

Clone Repo:

  • $ bundle install

  • $ bundle exec rake db:migrate

  • $ bundle exec rake db:seed

Check out seeded models

  • $ rails c

  • $ Book.all

  • $ Comment.all

  • $ b = Book.last

  • $ b.comments

  • $ b.destroy # associated comments are deleted too

  • $ c = Comment.first

  • $ c.commentable

Exercise:

  • fill in model relationship for "photos"

  • create controller for "photos"

  • create view pages for "photos"

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Steps to create polymorf app from scratch:

Start a new rails app:

	rails _4.0.2_ new polymorf
	
	rails g model comment content:text commentable_id:integer commentable_type:string
	rails g model book title:string
	rails g model video title:string
	rails g model photo caption:string

	rails g controller books index show

Edit Gemfile:

group :development, :test do
	gem 'pry'
	gem 'pry-rails'
	gem 'dotenv-rails'
end

Edit the Comments migration file

def change
  create_table :comments do |t|
    t.text :content
	t.belongs_to :commentable, polymorphic: true
	t.timestamps
  end
  add_index :comments, [:commentable_id, :commentable_type]
end

Edit comment.rb file:

class Comment < ActiveRecord::Base
  belongs_to :commentable, polymorphic: true
end

Edit book.rb file:

class Book < ActiveRecord::Base
  has_many :comments, as: :commentable
end

Edit video.rb file:

class Video < ActiveRecord::Base
  has_many :comments, as: :commentable
end	

Create books_controller.rb file:

rails g controller books index show

Edit books_controller.rb file:

class BooksController < ApplicationController
  def index
    @books = Book.all
  end

  def show
	@book = Book.find(params[:id])
	@book_comments = @book.comments
  end
end

Edit view/books/index.html.erb:

<h1>Books</h1>

<% @books.each do |book| %>

	<h2><a href="/books/<%= book.id%>"><li><%= book.title %></li></a></h2>

<% end %>

Edit view/books/show.html.erb

<h1><%=  @book.title %></h1>

<% @book_comments.each do |comment| %>

  <h2><li><%= comment.content %></li></h2>

<% end %>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment