Created
October 10, 2010 20:40
-
-
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
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
# 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 |
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
# Modify the routing helpers to use STI base classes instead of | |
# the descendant. | |
ActionDispatch::Routing::PolymorphicRoutes.send(:include, Kimono::Routing) |
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
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