ActiveRecord does not like attributes called type

by George on September 15, 2008

Here’s an interesting issue that I ran into while setting up a bunch of new models for a new application. Ultimately I discovered that “type” is a reserved field name for classes that inherit from ActiveRecord.

When I tried to create a new object, one of the fields would not accept a value and remained nil. Here’s what I saw from the console.

>> a = Attachment.new(:name => "some name", :type => "Video")
=> #<Attachment id: nil, name: "some name", type: nil, file_name: nil, activity_id: nil, created_at: nil, updated_at: nil>

I was not seeing an error except from my rspec test which conveniently popped up since I’m running autotest.

ActiveRecord::RecordInvalid in 'Attachment should create a new instance given valid attributes'
Validation failed: Type can't be blank

I had a many-to-one relationship between two tables. In my design there is an Activity model which has many Attachments. An Attachment can be of various file types. For example it could be a PDF, image, video, etc. Since I felt there would be very little difference in behavior for the different types, I simply added a type field to the Attachments table so I could evaluate that for a few various display options. I knew about the single-table inheritance that is built into ActiveRecord, but it didn’t occur to me right away that this could be the cause of my problem. When I tried to start up Mongrel and insert a new Attachment through my browser, I got failures again, but of course this was because the persistence failed. Ahhh, I had the validates_presence_of :type in my Attachment model class which of course won’t allow persistence of a nill value to the database. So I was back to why it was nil in the first place. I removed validates_presence_of from the model and of course the record was persisted with a nil value for the type field. And still no errors. I checked the database and just as expected found the record with a NULL value for type.

Next I inserted a new row to the database manually with a type value. Then it comes. The moment when I get to slap my forehead and feel kinda silly. As soon as I hit the refresh on the browser to see the list of Attachments, I get the following error:

The single-table inheritance mechanism failed to locate the subclass: 'Video'.
This error is raised because the column 'type' is reserved for storing the class in case of inheritance.
Please rename this column if you didn't intend it to be used for storing the inheritance class or
overwrite Attachment.inheritance_column to use another column for that information.

This is a great error. It’s well worded, tells me what the problem is and how to fix it. I just wish this would have been thrown when trying to persist an object to data with an invalid type. But hey, now I get to add that as my own validation method.

I eventually decided to use single-table inheritance after all because there turns out to be more that just a few differences in how I need to treat these attachments.

{ 0 comments… add one now }

Leave a Comment

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>