Search code examples
ruby-on-railspolymorphismsingle-table-inheritance

Rails STI using ONE form


I have a form that allows me to add files of different formats to a stream. So, a stream is made up of many files, these files are XML files but basically have different schemas. I have one form that allows the user to add whatever file they want, I am using STI (which works great when data is already in the table), my trouble is adding the data to the table.

The form has 1 input field, just a file_field that allows the user to select the file they want to upload. Since I only have one form I'm not able to instantiate the correct object, I have to do it programatically.. and I'm not sure how to do it.

Do I just (or can I) add a drop down with the possible types, and call that field 'type' so that when the form is submitted rails will instantiate the write type of object because the type attribute is provided?

What is the best practice for this.. I'm running rails 2.3.4.


Solution

  • I found a solution at http://coderrr.wordpress.com/2008/04/22/building-the-right-class-with-sti-in-rails/#comment-1826

    class GenericClass < ActiveRecord::Base
      class << self
        def new_with_cast(*a, &b)
          if (h = a.first).is_a? Hash and (type = h[:type] || h['type']) and (klass = type.constantize) != self
            raise "wtF hax!!"  unless klass < self  # klass should be a descendant of us
            return klass.new(*a, &b)
          end
    
          new_without_cast(*a, &b)
        end
        alias_method_chain :new, :cast
      end
    end
    

    Which worked great for me with minimal code - I don't know if its hackish or not but it works, and is rather clean. I liked the fact that its only 10ish lines of code.