zetacu
zetacu

Reputation: 17612

Update/Delete wrong record because of ActiveRecord "type"

I have 2 tables Foo and FooArchive, where FooArchive is a replica of Foo. FooArchive is for storing old data from Foo in order to optimize and keep the first from growing too big.

class Foo < ActiveRecord::Base
end

class FooArchive < ActiveRecord::Base
end

Foo is subclassed:

class OneFoo < Foo
end

class TwoFoo < Foo
end

When I archive a record from Foo to FooArchive it also copies its type. When I get a record from FooArchive for example the last, once I get that record if I try to modify it like updating or deleting it will read the type and try to get the record from the Foo table instead of FooArchive.

foo_archive = FooArchive.last
SELECT `foo_archives`.* FROM `foo_archives` ORDER BY `foo_archives`.`id` DESC LIMIT 1

foo_archive.reload
SELECT `foos`.* FROM `foos` WHERE `foos`.`type` IN ('OneFoo') AND `foos`.`id` = 35 LIMIT 1
ActiveRecord::RecordNotFound: Couldn't find OneFoo with id=35 [WHERE `foos`.`type` IN ('OneFoo')]

I sort of understand why it is trying to find the record in the other table since the type belongs to that table.

Is there a way to make it work without modifying the data/columns, I'm thinking of getting rid of active record for this model but haven't found the way to do it.

In this case I'm using:

Upvotes: 0

Views: 108

Answers (1)

zetetic
zetetic

Reputation: 47548

Rails assumes your FooArchive model is using STI (Single Table Inheritance) to instantiate OneFoo objects. You should be able to disable this with:

class FooArchive < ActiveRecord::Base
  self.inheritance_column = nil

Note: untested. You may need to use a non-existing column instead of nil to make this work.

Upvotes: 2

Related Questions