Polymorphic Associations

#98 Polymorphic Associations
9/17/2017

Summary

Advancing from Single Table Inheritance, learn how Polymorphic Associations differ and tricks to simplify their usage.
4
rails model 10:31 min

Summary

Terminalrails g scaffold company name website
rails g scaffold employees first_name last_name email birth_date:date
rails g model note notable:references{polymorphic} content:text
database migrationsclass CreateNotes < ActiveRecord::Migration[5.1]
  def change
    create_table :notes do |t|
      t.references :notable, polymorphic: true
      t.text :content

      t.timestamps
    end
  end
end

create_table "notes", force: :cascade do |t|
  t.string "notable_type"
  t.integer "notable_id"
  t.text "content"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.index ["notable_type", "notable_id"], name: "index_notes_on_notable_type_and_notable_id"
end
note.rbclass Note < ApplicationRecord
  belongs_to :notable, polymorphic: true
end
employee.rbclass Employee < ApplicationRecord
  has_many :notes, as: :notable
end
company.rbclass Company < ApplicationRecord
  has_many :notes, as: :notable
end
routes.rbRails.application.routes.draw do
  resources :companies do
    resources :notes, module: :companies
  end

  resources :employees do
    resources :notes, module: :employees
  end

  ...
end
notes_controller.rbclass NotesController < ApplicationController
  def new
    @note = @notable.notes.new
  end

  def create
    @note = @notable.notes.new note_params
    @notable.save
    redirect_to @notable, notice: "Your note was successfully posted."
  end

  private

    def note_params
      params.require(:note).permit(:content)
    end
end
employees/notes_controller.rbclass Employees::NotesController < NotesController
  before_action :set_notable

  private

    def set_notable
      @notable = Employee.find(params[:employee_id])
    end
end
companies/notes_controller.rbclass Companies::NotesController < NotesController
  before_action :set_notable
  
  def create
    # NOTIFY
    super
  end

  private

    def set_notable
      @notable = Company.find(params[:company_id])
    end
end
employees/show.html.erb<%= render partial: "notes/notes", locals: {notable: @employee} %>
<%= render partial: "notes/form", locals: {notable: @employee} %>
companies/show.html.erb<%= render partial: "notes/notes", locals: {notable: @company} %>
<%= render partial: "notes/form", locals: {notable: @company} %>
notes/_form.html.erb<%= form_with(model: [notable, Note.new], local: true) do |form| %>
  <div class="field">
    <%= form.label :content %><br/>
    <%= form.text_area :content %>
  </div>
  <%= form.submit class: "btn btn-primary" %>
<% end %>
notes/_notes.html.erb<h3>Notes</h3>
<% notable.notes.each do |note| %>
  <p>
    <hr>
    <%= note.content %>
    <em><%= time_ago_in_words note.created_at %></em>
  </p>
<% end %>


00000000000000000000000000000000?d=mm&f=y&s=64
hackvan said about 1 month ago:

Excellent episode, very useful.

Login to Comment