silverstripe-framework: [ORM] Default values set in $db can not be relied upon for sub-class tables

The “Default values for new database columns” functionality documented here can not be relied upon if the field is being introduced to a sub-class table instead of the base table.

For example, when introducing a new database property to Image, a default value specified in the field constructor within $db will not be applied to existing records which only exist in the File table and not the Image table.

In the case of Image, this issue arises because a given Image object must have a record in the base File table, but it may or may not have a record in the Image table (assuming an Image table exists). At the time of introducing a new field to the Image table and building the database, only Image objects that already have a record in the Image table will receive the default value specified in the constructor in the $db array.

The next time an Image is saved (write() called) the specified default value may be applied, but until that time a null value will be returned for the newly introduced field when reading the object. Also, if write() is called from a from a form interface the default probably won’t be applied at this point because the form will have been pre-populated with a null value and it will try to save this in to the object.

In contrast, if you introduce a new field to File, all Image objects will receive the default value specified in $db at build time because all Image objects have a record in the File table.

*Note that we’re talking about the $db array here, not the $defaults array. *Also File and Image is probably a bad example to use because it’s all been re-worked in master… I’ve described the issue as it applies to 3.x


WAS:

I’m just upgrading my boilerplate project and noticed I was having trouble with Images. A bunch of them seemed to be behaving only as Files all of a sudden. I checked the database and while there were lots of records in the File table with a ClassName of Image, there were only a handful of records in the Image table.

There should be a record in the Image table for each ClassName=Image record in the File table right?

To test I deleted the Image table by removing the extension that’s adding properties to Image, and rebuilt the database. Then I created a simple extension to add a $db property to Image, and rebuilt again. An Image table is built but it is empty. Image::get() comes up empty.

Anyone know what’s going on here? I’m going to be away for a few days but here are some test files if anyone wants to investigate: http://cl.ly/402J242f3D10/ImageTableTest.zip

About this issue

  • Original URL
  • State: open
  • Created 9 years ago
  • Comments: 45 (45 by maintainers)

Commits related to this issue

Most upvoted comments

Sam rolled this up into a more generic issue: https://github.com/silverstripe/silverstripe-framework/issues/8908