Casts insert on a model

Viewed 47

I am using Laravel 5.4.

I have set a $casts array:

protected $casts =
[
   'language_meta' => 'object'
];

But when I'm inserting an array :

[
 "meta_page_title_cc__c" => "Historic villa for sale within moments of central Florence"
 "meta_page_title_fr__c" => null
 "meta_page_title_it_cc__c" => "Villa prestigiosa in vendita situata appena fuori il centro storico di"
 "meta_page_title_ru_cc__c" => null
 "meta_description_it_cc__c" => "Situata in uno dei sobborghi residenziali più prestigiosi di Firenze, questa straordinaria villa storica in vendita è una rara scoperta architettonica che unisce al suo interno magnifiche caratteristiche originali."
 "meta_description_fr_cc__c" => null
 "meta_description_ru_cc__c" => null
]

I run a json_encode on that array and I get :

{
"meta_page_title_cc__c": "Historic villa for sale within moments of central Florence",
"meta_page_title_fr__c": null,
"meta_page_title_it_cc__c": "Villa prestigiosa in vendita situata appena fuori il centro storico di",
"meta_page_title_ru_cc__c": null,
"meta_description
_it_cc__c ":"
Situata in uno dei sobborghi residenziali pi\u00f9 prestigiosi di Firenze,
questa straordinaria villa storica in vendita \u00e8 una rara scoperta architettonica che unisce al suo interno magnifiche caratteristiche originali.
","
meta_description_fr_cc__c ": null,
"meta_description_ru_cc__c": null
} 

I am then trying to insert this and I suspect because of the "casts" it is then inserting the data as so :

"{\"meta_page_title_cc__c\":\"Luxury Property For Sale near Montecatini Tuscany\",\"meta_page_title_fr__c\":null,\"meta_page_title_it_cc__c\":\"Immobili di lusso in vendita vicino Montecatini Toscana\",\"meta_page_title_ru_cc__c\":null,\"meta_description_it_cc__c\":\"Casolare con finitura di pregio in vendita - Montecatini Toscana\",\"meta_description_fr_cc__c\":null,\"meta_description_ru_cc__c\":null}"

I am unable to set my column as "json" via an migration, so have set the column as longtext.

Is there a way to insert the data correctly, then decode that data out to be as expected, via the $casts option? I note that removing the $casts and the json data goes in correctly.

Maybe there's a way to work with $casts and store the object correctly?

Thanks

1 Answers

You can achieve this using Mutators like so:

class MyModel extends Model
{
    public function setLanguageMetaAttribute(array $meta)
    {
        $this->attributes['language_meta'] = json_encode($meta); // Store as json encoded string
    }

    public function getLanguageMetaAttribute(string $meta)
    {
        return json_decode($meta, true); // Return as associative php array
    }
}

Now when you can use it like so:

    $model = MyModel::find($some_id); // Or however you want to select
    $model->language_meta = [
        "meta_page_title_cc__c" => "Historic villa for sale within moments of central Florence"
        "meta_page_title_fr__c" => null
        "meta_page_title_it_cc__c" => "Villa prestigiosa in vendita situata appena fuori il centro storico di"
        "meta_page_title_ru_cc__c" => null
        "meta_description_it_cc__c" => "Situata in uno dei sobborghi residenziali più prestigiosi di Firenze, questa straordinaria villa storica in vendita è una rara scoperta architettonica che unisce al suo interno magnifiche caratteristiche originali."
        "meta_description_fr_cc__c" => null
        "meta_description_ru_cc__c" => null
    ];
    
    $model->save(); // Persists in DB as json

And when you go to retrieve it, it will already be an array, so you could do for example:

    $model = MyModel::find($some_id); // Or however you want to select

    foreach ($model->language_meta as $key => $value) {
        // Whatever you want to do with the meta here
    }
Related