This would be super useful! I've been working on a legacy project, and the 
ability to map class name to what's stored in the DB would be fantastic.

On Thursday, 10 July 2014 11:34:05 UTC-4, Eric Roberts wrote:
>
> I recently tried to retrofit STI on a database table that had already 
> existed for a while. Here's a basic outline of the scenario.
>
>    1. I had a class 'Code' and a database table 'codes'.
>    2. 'Code' had an attribute 'units', which could be either '$' or '%'
>    3. I wanted the STI classes to be Code::Dollar or Code::Percent
>
> I successfully implemented this with the following:
>
> class Code
>   self.inheritance_column = 'units'
>
>   class << self
>     def find_sti_class(units)
>       unit_class_for[units]
>     end
>
>     def sti_name
>       unit_class_for.invert[self]
>     end
>
>     def unit_class_for
>       {
>         '$' => Code::Dollar,
>         '%' => Code::Percent
>       }
>     end
>   end
> end
>
> This works perfectly if I use it in the following way:
>
> Code::Dollar.new(initialization_hash)
> Code::Percent.new(initialization_hash)
>
> However, if I do just Code.new(units: '$') or something.build(units: '$'), 
> I get an error like the following:
>
> ActiveRecord::SubclassNotFound: Invalid single-table inheritance type: $ is 
> not a subclass of Code
>
> What I really want is for Code.new(units: '$') to return me a Code::Dollar
>  object.
>
> I was able to trace the lookup of the class name into
> ActiveRecord::Inheritance::ClassMethods#subclass_from_attrs. From there I 
> could see that it was trying to build the class name from the units value 
> in the database, which obviously doesn't work as there isn't a class named 
> $ or %.
>
> What I'm really trying to do is setup STI to work correctly when the value 
> of the database column doesn't correspond to a class name. As there is 
> already another method called find_sti_class, it seems curious that we 
> couldn't use it inside of subclass_from_attrs in order to make it work in 
> this way. I did try it and was successful, but as find_sti_class is a 
> private method, I did not submit a patch using this.
>
> So, after all of that, I guess what I'm after is finding out if doing such 
> a thing is possible in Rails as is. If not, would a patch to make it 
> possible be desired by people other than myself? And if that patch made 
> find_sti_class part of the public interface, would that be likely to be 
> accepted?
>

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/rubyonrails-core.
For more options, visit https://groups.google.com/d/optout.

Reply via email to