Odd behaviour of update_attributes in STI table

I just noticed this odd behaviour (in rails 2.2.2). It looks like changing the type with update_attributes *doesn't* work (but returns true!), but changing the field and then saving it *does* work. Here i have an STI situation where TeachingObject and LearningObject extend Resource.

The bit where update_attributes returns true, yet seems to fail, is rather disconcerting. Can anyone explain what's going on here?

thanks -max

resource = Resource.first

=> #<TeachingObject id: 59, name: "Clarinet bite point close-up", description: "", type: "TeachingObject", <etc> >

resource.update_attributes(:type => "LearningObject")

=> true

resource = Resource.first

=> #<TeachingObject id: 59, name: "Clarinet bite point close-up", description: "", type: "TeachingObject", <etc> >

resource.type = "LearningObject"

=> "LearningObject"

resource.save

=> true

resource = Resource.first

=> #<LearningObject id: 59, name: "Clarinet bite point close-up", description: "", type: "LearningObject", <etc> >

I just noticed this odd behaviour (in rails 2.2.2). It looks like changing the type with update_attributes *doesn't* work (but returns true!), but changing the field and then saving it *does* work. Here i have an STI situation where TeachingObject and LearningObject extend Resource.

The bit where update_attributes returns true, yet seems to fail, is rather disconcerting. Can anyone explain what's going on here?

I believe that the type column is marked as a protected attribute or something along those lines.

Fred

Frederick Cheung wrote:

I just noticed this odd behaviour (in rails 2.2.2). � It looks like changing the type with update_attributes *doesn't* work (but returns true!), but changing the field and then saving it *does* work. �Here i have an STI situation where TeachingObject and LearningObject extend Resource.

The bit where update_attributes returns true, yet seems to fail, is rather disconcerting. �Can anyone explain what's going on here?

I believe that the type column is marked as a protected attribute or something along those lines.

Fred

ahhh, well that would explain it. It would also explain why update_attribute returns true - it just silently ignores the protected fields. It's a bit annoyin that the api doesn't mention this: to quote

Single table inheritance

Active Record allows inheritance by storing the name of the class in a column that by default is named "type" (can be changed by overwriting Base.inheritance_column). This means that an inheritance looking like this:

class Company < ActiveRecord::Base; end class Firm < Company; end class Client < Company; end class PriorityClient < Client; end

When you do Firm.create(:name => "37signals"), this record will be saved in the companies table with type = "Firm". You can then fetch this row again using Company.find(:first, "name = ‘37signals’") and it will return a Firm object.

If you don‘t have a type column defined in your table, single-table inheritance won‘t be triggered. In that case, it‘ll work just like normal subclasses with no special magic for differentiating between them or reloading the right type with find.

Note, all the attributes for all the cases are kept in the same table. Read more: www.martinfowler.com/eaaCatalog/singleTableInheritance.html

unquote.

anyway, thanks Fred. max