Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 612
Rabbott Avatar asked Feb 01 '10 06:02

Rabbott


People also ask

What is STI in rails?

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:

Is there a “rails way” to do multi-step forms?

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.

What is STI in ActiveRecord?

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.

What is single table inheritance in rails?

Single table inher­i­tance (STI) in Rails allows you to store Ruby sub­class­es in the same data­base table. Let’s get start­ed with a brand-new Rails pro­ject to learn what that means. I’ll be using Rails 4.2.3 and SQLite as the data­base. Gen­er­ate a migra­tion for it. To imple­ment STI, we add a column called type of type string to the class.


1 Answers

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.

like image 171
Rabbott Avatar answered Sep 28 '22 03:09

Rabbott