Last active
April 25, 2017 09:54
-
-
Save kirel/7597979 to your computer and use it in GitHub Desktop.
Build correct sti subclass
This file contains 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
# STI subclass building backported from Rails 4 to use in Rails 3.2 - see | |
# https://github.com/rails/rails/commit/89b5b31cc4f8407f648a2447665ef23f9024e8a5 | |
# Usage: | |
# include BuildStiSubclass # in your model and be done | |
module BuildStiSubclass | |
extend ActiveSupport::Concern | |
included do | |
attr_accessible inheritance_column | |
end | |
module ClassMethods | |
# Determines if one of the attributes passed in is the inheritance column, | |
# and if the inheritance column is attr accessible, it initializes an | |
# instance of the given subclass instead of the base class | |
def new(*args, &block) | |
if (attrs = args.first).is_a?(Hash) | |
if subclass = subclass_from_attrs(attrs) | |
return subclass.new(*args, &block) | |
end | |
end | |
# Delegate to the original .new | |
super | |
end | |
# Detect the subclass from the inheritance column of attrs. If the inheritance column value | |
# is not self or a valid subclass, raises ActiveRecord::SubclassNotFound | |
# If this is a StrongParameters hash, and access to inheritance_column is not permitted, | |
# this will ignore the inheritance column and return nil | |
def subclass_from_attrs(attrs) | |
subclass_name = attrs.with_indifferent_access[inheritance_column] | |
return nil if subclass_name.blank? || subclass_name == self.name | |
unless subclass = subclasses.detect { |sub| sub.name == subclass_name } | |
raise ActiveRecord::SubclassNotFound.new("Invalid single-table inheritance type: #{subclass_name} is not a subclass of #{name}") | |
end | |
subclass | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
👍 Nice one