Skip to content

Instantly share code, notes, and snippets.

@jimsynz
Created October 10, 2010 20:40
Show Gist options
  • Save jimsynz/619545 to your computer and use it in GitHub Desktop.
Save jimsynz/619545 to your computer and use it in GitHub Desktop.
Patch ActionDispatch to build routes based on the STI base class. http://sociable.co.nz/post/1286186984/patch-rails3-sti
# app/models/meats.rb
class Meat < ActiveRecord::Base
end
# app/models/bacon.rb
class Bacon < Meat
end
# app/models/chunky_bacon.rb
class ChunkyBacon < Bacon
end
# Modify the routing helpers to use STI base classes instead of
# the descendant.
ActionDispatch::Routing::PolymorphicRoutes.send(:include, Kimono::Routing)
module Kimono
module Routing
def self.included(base)
base.class_eval do
define_method :base_model do |model|
if model.is_a?(String) || model.is_a?(Symbol)
model
else
klass = if model.is_a? Class
model
else
model.class
end
# Test whether the parent class is a
# Mongoid model.
while (klass.superclass.include? ::Mongoid::Document)
klass = klass.superclass
end
# You might
# wish to test for AR instead
# klass = until (klass.superclass == ActiveRecord::Base)
# klass = klass.superclass
# end
klass
end
end
# Unfortunately I can find no nicer way than replacing the
# entire build_named_route_call method. For two such small
# changes it seems like overkill.
define_method :build_named_route_call_with_sti do |records, inflection, options = {}|
unless records.is_a?(Array)
record = extract_record(records)
route = []
else
record = records.pop
route = records.map do |parent|
if parent.is_a?(Symbol) || parent.is_a?(String)
parent
else
ActiveModel::Naming.plural(base_model(parent)).singularize
end
end
end
if record.is_a?(Symbol) || record.is_a?(String)
route << record
else
route << ActiveModel::Naming.plural(base_model(record))
route = [route.join("_").singularize] if inflection == :singular
route << "index" if ActiveModel::Naming.uncountable?(base_model(record)) && inflection == :plural
end
route << routing_type(options)
action_prefix(options) + route.join("_")
end
alias_method_chain :build_named_route_call, :sti
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment