Skip to content

Instantly share code, notes, and snippets.

@kirel
Last active April 25, 2017 09:54

Revisions

  1. kirel revised this gist Nov 22, 2013. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions build_sti_subclass.rb
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,5 @@
    # STI subclass building backported from
    # STI subclass building backported from Rails 4 to use in Rails 3.2 - see
    # https://github.com/rails/rails/commit/89b5b31cc4f8407f648a2447665ef23f9024e8a5
    # use on demand by extending classes you want this for by including this module
    # Usage:
    # include BuildStiSubclass # in your model and be done
    module BuildStiSubclass
  2. kirel created this gist Nov 22, 2013.
    38 changes: 38 additions & 0 deletions build_sti_subclass.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,38 @@
    # STI subclass building backported from
    # https://github.com/rails/rails/commit/89b5b31cc4f8407f648a2447665ef23f9024e8a5
    # use on demand by extending classes you want this for by including this module
    # 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