ActiveRecord Custom Type Naming Schema

I am dealing with a table that already has a column with natural type names. For example. a provider column already exists that has the value foo or bar. I want to use STI in this table, using existing type names, since it seems silly to add an extra column called "type" to use Active Record. The problem is that these type names do not exactly match the ruby ​​classes. I was hoping I could set up a custom mapping, for example. Class1 => foo, Class2 => bar.

I tried the following:

# In the base class set_inheritance_column :provider # In Class1 def self.sti_name 'foo' end # In Class2 def self.sti_name 'bar' end 

But this does not seem to shorten it, I get:

 The single-table inheritance mechanism failed to locate the subclass: 'foo' ... activerecord (3.0.8) lib/active_record/base.rb:923:in `find_sti_class' 

It seems that ActiveRecord is only designed to handle fully qualified class names and demodularized class names. I am not sure that the purpose of creating the protected method sti_name is completely absent.

I am going to delve into the scope and override ActiveRecord :: Base.compute_type. Before I do this, has anyone done this before? Is this a wild goose chase?

Can rails handle custom type names or am I sticking with Ruby class names?

Update

I got this to work with:

 # In the base class def self.find_sti_class(type_name) # Do mapping from foo/bar to Class1/Class2 ... end 

I am still afraid to face some problems in the future. Is this the right way to do this?

+7
source share
2 answers

I had a similar situation and found a solution at this link: https://gist.github.com/1381880

+2
source

Looking at the AR code and just focusing on sti_name and instantiate .. it seems you might have enough for the monkey to establish these two methods.

I have no experience with this, but it does not look incredibly complicated. Here's what instantiate looks like:

 def instantiate(record) model = find_sti_class(record[inheritance_column]).allocate model.init_with('attributes' => record) model end 

Ideally, you want to scan the code for anything that refers to something like record[inheritance_column] or just inheritance_column , and draw your own matching code there. Just a quick look, and it seems that it is not used in many places.

I would say that you are trying to make it possible :), but you will need test cases for the base instance + things in which associations are involved to make sure that AR can find and build the correct SQL for different cases.

This is clear, although the AR was not built with what you are trying to recall, since the use of inheritance_column in the code has not been explicitly deleted anywhere. So why you need to delve more into the code.

+1
source

All Articles