I made a big work refactoring tonnes of code, and also made big changes to db schema. And now I am trying to write a rake task to migrate records from old tables to a new one.
I am having such classes:
#app/models/restream/service.rb
class Restream::Service < ActiveRecord::Base
def self.types
%w(custom multiple_destinations_service one_destination_service) +
Restream::Custom.types + Restream::MultipleDestinationsService.types
end
def self.find_sti_class(type_name) #allows to find classes by short names
type_name = "Restream::#{type_name.camelcase}".constantize
super
end
end
#app/models/restream/custom.rb
class Restream::Custom < Restream::Service
def self.sti_name
"custom"
end
def self.types
%w(periscope odnoklassniki vkontakte)
end
end
#app/models/restream/periscope.rb
class Restream::Periscope < Restream::Custom
def self.sti_name
"periscope"
end
end
Everything works just fine. Until I'm trying to add records manually. In my previous version I had such a structure:
class Restream::Custom < ActiveRecord::Base
def self.types; %w(custom periscope vkontakte); end
end
class Restream::Periscope < Restream::Custom
def self.sti_name; 'periscope'; end
end
And now I'm trying simply get all records from old restream_custom
table and just copy type. Roughly:
Restream::Custom.create(type: old_restream_custom.type)
And that fails saying:
ActiveRecord::SubclassNotFound: Invalid single-table inheritance type: periscope is not a subclass of Restream::Custom
It's obviously not! But anyway I already have a bunch of records with type: 'periscope'
, so that I know it's a valid value.
What's the reason for this, and how can I fix this behaviour?
======
I can see two ways:
1) Set type
to Restream::Periscope
, not just a periscope
. But that creates records, that can't be found by Restream::Periscope.find_each
or Restream::Custom.find_each
or smth like that, 'cause it will search for records with periscope
in its type
column, not a Restream::Periscope
.
2) Select from restream_custom
table only records with each types of custom
, periscope
, etc. and create Restream::Periscope
for periscopes, not Restream::Custom
and trying to provide a correct type here. But I found it kind of unpretty, not-DRY and unnecessary, and wonder if I can do smth more beautiful with it.