good-migrations
good-migrations copied to clipboard
Polymorphic Associations
Hey, I'm having trouble with good_migrations
in a migration where one of the classes has a polymorphic association. Just wondering if anyone has hit this issue before, or has any tips?
Here's a rough example of what it looks like:
class MigrateWidgets < ActiveRecord::Migration[5.2]
class Widget < ActiveRecord::Base
belongs_to :poly, polymorphic: true
end
class Foo < ActiveRecord::Base; end
class Bar < ActiveRecord::Base; end
def up
# Example 1; GoodMigrations::LoadError (attempting to load app/models/foo.rb)
Widget.where(poly_type: 'Foo').includes(:poly).find_each do |widget|
# ...
end
# Example 2; GoodMigrations::LoadError (attempting to load app/models/bar.rb)
Widget.where(poly_type: 'Bar').last.poly
end
end
As a workaround, using require
to explicitly load the classes that are used in the polymorphic associations works, but obviously it's not ideal...
A bit late to the party, but if you don't need the STI (ex, you just want to edit some fields), you can do this:
class MigrateWidgets < ActiveRecord::Migration[5.2]
class Widget < ActiveRecord::Base
self.inheritance_column = 'this_column_doesnt_exist'
end
# ...
end
This way, Rails doesn't detect the STI for your custom model, so it doesn't try to load sub-models from the top-level.
Clever! @MaxLap would you be interested in sending a PR to the README to include this pro-tip?
Sorry, I just realized my tip doesn't apply here. My tip is for dealing with STI, not with polymorphic associations.
@searls I don't know if you still want this in the README, but since it's so short, I wouldn't know where to put it or how to contextualize it. I think you are better placed to the the change. Here is a bit of an explanation that you could build upon:
Dealing with STI
When redefining a model inside of a migration class, a problem happens if the model uses STI (single table inheritance): Rails will try to load the actual model from the type
column. The load is done from the top-level namespace, so you can't define more models for each sub-models in the migration class, they won't be found.
Depending on your situation, you may not need STI at all for your migration. In that case, a solution is to set the STI column (normally type
) to a column that doesn't exist, so that Rails doesn't try to do STI.
class ChangeSomething < ActiveRecord::Migration
class User < ActiveRecord::Base
self.inheritance_column = 'this_column_doesnt_exist'
end
end