

* Allow the user to pass an array instead of the value object itself. Public function set($model, $key, $value, $attributes) Return new AddressValue(json_decode($value, true)) * We'll need this to handle nullable columns Public function get($model, $key, $value, $attributes) Use Illuminate\Contracts\Database\Eloquent\CastsAttributes Check out the data transfer object package docs to see how these can all be defined.Īt this point, the Address custom cast might look something like this: namespace App\Casts Spatie's package even allows us to define arrays of things and also unions types! Some of which will be native in PHP 8. We can also mark properties as nullable to make them optional.
#PHP JSON DECODE HAS QUERY STRING FREE#
Feel free to store it anywhere you like, such as App\DataTransferObjects or even in the same directory as your models.Īlso note that we're not limited to primitive types here - we can include other classes including nested data transfer objects. I like to store these in App\Values because I'll typically be adding domain-specific methods that make it more like a value object than a plain DTO. Use Spatie\DataTransferObject\DataTransferObject Ĭlass Address extends DataTransferObject implements Castable We just need to define the properties: namespace App\Values

Use Illuminate\Contracts\Database\Eloquent\Castable Now imagine casting to an instance of a specific value object class via Laravel's custom casts: namespace App\Models īut take that another step and make the value object class castable by implementing the Castable interface: namespace App\Values This is cool too, but in practice I've found an associative array is often easier to work with. This does the same thing, but for a stdClass object. You may also be familiar with: namespace App\Models This will automatically cast an array (associative or numeric) to JSON, and back again. You may be familiar with the following built-in cast: namespace App\Models So what are our options for working with JSON columns in Laravel? And modern database engines can index and natively query inside these JSON structures quite well. JSON columns effectively give us the benefits (and downsides) of a NoSQL/document-based database inside our relational database. There are plenty of reasons why you may want to consider a JSON column. Maybe we have a collection of items that aren't deserving of their own table. The Laravel docs has an excellent example of how we can cast to and from multiple columns into a single value object.īut in some cases we may want a nested structure, or maybe we have a lot of optional fields that we don't want cluttering the table structure. We could create dedicated columns in the database for each attribute. However, the database won't be able to query the parts easily, and depending on the number of type of attributes, it could get unwieldy. So we may be tempted to create our own conventions. We may not always be so lucky with our value objects though.
#PHP JSON DECODE HAS QUERY STRING HOW TO#
For example, a date can represent the year, month, and day as Y-m-d but we can still pull it apart if needed, and the database knows how to query the parts individually.

Some may have have special formats that allow us to represent the individual attributes as a single string. That's part of what separates them from primitive types like strings and integers. Most value objects have multiple attributes. Have you ever wanted to access an attribute of an Eloquent model as a value object, similar to how Eloquent lets us work with dates via Carbon? $user->address->calculateDistance($otherUser->address)
