Skip to content

v0.4.0 — Cast-mode storage via DataField value object

Choose a tag to compare

@sambhav-aggarwal sambhav-aggarwal released this 20 Jun 16:34

Ground-up rework of JSON-mode storage. The trait-based HasDataFieldsJson is replaced by a Laravel custom cast that hydrates one self-describing DataField document per JSON column — schema and values merged, no envelope, no separate schema column, multiple "forms" per model.

Pre-release package, no compatibility shim provided. See the migration guide in the README and the CHANGELOG for the full list of breaking changes.

Headline changes

New cast surface

use Ssntpl\DataFields\Support\DataField;

class User extends Model
{
    protected $casts = [
        'preferences' => DataField::class,
    ];
}

$user->preferences = DataField::section(items: [
    ['key' => 'dark_mode', 'type' => 'bool', 'value' => true],
    ['key' => 'language',  'type' => 'text', 'value' => 'en'],
]);
$user->preferences->dark_mode->value;          // bool true
$user->preferences->dark_mode->value = false;
$user->save();
  • Ssntpl\DataFields\Support\DataField — cast value object (Castable, IteratorAggregate, JsonSerializable, ArrayAccess, Countable).
  • Ssntpl\DataFields\Casts\DataFieldCast — Laravel cast (resolved via Castable::castUsing; consumers write DataField::class).
  • Ssntpl\DataFields\Support\FieldType — PHP 8.1 backed enum covering all 12 leaf + 3 container types.
  • Ssntpl\DataFields\Concerns\FieldAttributes — shared trait between cast and row modes.

Renames

Before After
Ssntpl\DataFields\Models\DataField (Eloquent model) Ssntpl\DataFields\Models\DataRow
Ssntpl\DataFields\Casts\FieldValueCast Ssntpl\DataFields\Casts\RowValueCast
Ssntpl\DataFields\Traits\HasDataFields Ssntpl\DataFields\Concerns\HasDataFields
Config key data_field_model data_row_model
Column meta_data meta
Constants DataField::BOOL etc. FieldType::Bool->value etc.

DataRow also gains a label column (the short display string) so the description column is freed up for actual long-form helper text — matching the cast-mode shape.

Removed

  • HasDataFieldsJson trait — replaced by the cast.
  • JsonModeMigration, SchemaValidator, FieldValue, DataSetValue, FieldLike — folded into DataField or no longer needed.
  • DataSet model + trait + data_sets table — grouping is a consuming-app concern; cast-mode containers handle the structured case.
  • Envelope handling ({"version": "1.0", ...} wrapping), strict_writes config, clearDataFieldsCache().

Other improvements

  • ValueCaster accepts FieldType|string at every entry point.
  • DataRow::delete() cascades wrapped in DB::transaction().
  • FILE vs FILES decided by declared type, never by stored structure (empty files round-trips as [], not null).
  • select_* rules use Rule::in() and reject , / | in option keys.
  • data_fields indexed on (owner_id, owner_type, key) as a single composite.
  • auto_load_migrations config flag for consumers who'd rather skip vendor:publish.
  • HasDataFields gains getFieldValue / setFieldValue upsert helpers.

Migration from 0.2.x

- use Ssntpl\DataFields\Traits\HasDataFields;
+ use Ssntpl\DataFields\Concerns\HasDataFields;

- use Ssntpl\DataFields\Models\DataField;
+ use Ssntpl\DataFields\Models\DataRow;

Replace HasDataFieldsJson with the DataField::class cast — see the README's "Migrating from 0.2.x" section for a worked example.

Full changelog

See CHANGELOG.md for the complete list of changes and rationales.