Last active
August 29, 2015 14:19
-
-
Save oojikoo-gist/681404127816712d1f47 to your computer and use it in GitHub Desktop.
rails: polymorphic module
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
########################################################## | |
# polymorphic as module | |
########################################################## | |
# app/models/comment.rb | |
# | |
class Comment < ActiveRecord::Base | |
belongs_to :commenter, :polymorphic => true | |
end | |
module Commentable | |
has_many :comments, as: :commentable | |
end | |
class Timesheet < ActiveRecord::Base | |
include Commentable | |
end | |
class ExpenseReport < ActiveRecord::Base | |
include Commentable | |
end | |
module Commentable | |
def self.included(base) | |
base.class_eval do | |
has_many :comments, as: :commentable | |
end | |
end | |
end | |
# app/models/concerns/commentable.rb | |
module Commentable | |
extend ActiveSupport::Concern | |
included do | |
has_many :comments, as: :commentable | |
end | |
end | |
# controller | |
class CommentsController < ApplicationController | |
before_filter :find_commenter | |
def create | |
@comment = @commenter.comments.create(params[:comments]) | |
respond_to do |format| | |
format.html {redirect_to :controller => @commenter.class.to_s.pluralize.downcase, :action => :show, :id => @commenter.id} | |
end | |
end | |
private | |
def find_commenter | |
klass = params[:commenter_type].capitalize.constantize | |
@commenter = klass.find(params[:commenter_id]) | |
end | |
end | |
########################################################## | |
########################################################## | |
# Combining has_many :through and polymorphic association | |
########################################################## | |
# There can be special cases where you need has_many :through with polymorphic association. Although not difficult to understand/implement, one might get confused the first time. So lets say Professor wants to know what courses/labs were assigned to his phd students/TAs. This can be made possible by doing the following. | |
``` | |
# /app/models/professor.rb | |
class Professor < ActiveRecord::Base | |
has_many :teaching_assistants | |
has_many :course_tas, through: :teaching_assistants, source: :ta_duty, source_type: 'Course' | |
has_many :lab_tas, through: :teaching_assistants, source: :ta_duty, source_type: 'Lab' | |
end | |
``` | |
``` | |
# /app/models/teaching_assistant.rb | |
class TeachingAssistant < ActiveRecord::Base | |
belongs_to :professors | |
belongs_to :ta_duty, polymorphic: true | |
end | |
``` | |
# That’s it, we have combined has_many :through and polymorphic association. To test you can make queries like Professor.first.course_tas. Note that we have added association between Professor and TAs, so make sure you make corresponding changes. | |
# !!!!! When adding Bi-directional Associations in rails application, one uses inverse_of: option provided by Active Record. inverse_of: does not work with polymorphic associations. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment