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.
STI enables you to use all the typical model methods in Rails, like .new, .create or any of the .find helper methods that make Rails so awesome, to both the super-class and the sub-classes within a single table. For example, using STI enables me to write code like this:
Unlike regular CRUD interfaces, there’s not a prescribed “Rails Way” to do multi-step forms. This, plus the fact that multi-step forms are often inherently complicated, can make them a challenge.
STI is basically the idea of using a single table to reflect multiple models that inherit from a base model, which itself inherits from ActiveRecord::Base. In the database schema, sub-models are indicated by a single “type” column.
Single table inheritance (STI) in Rails allows you to store Ruby subclasses in the same database table. Let’s get started with a brand-new Rails project to learn what that means. I’ll be using Rails 4.2.3 and SQLite as the database. Generate a migration for it. To implement STI, we add a column called type of type string to the class.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With