Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Casts property on custom pivot model is not honored for JSON castable attributes #18135

Closed
jrhenderson1988 opened this issue Feb 27, 2017 · 2 comments

Comments

@jrhenderson1988
Copy link
Contributor

jrhenderson1988 commented Feb 27, 2017

#- Laravel Version: 5.4.11

  • PHP Version: 7.0.15
  • Database Driver & Version: MySQL driver - Maria DB 10.2.3

Description:

When defining a BelongsToMany relationship on an Eloquent model and specifying a custom pivot model with the using method, I am finding that the $casts property on the custom pivot model is not honoured for JSON castable attributes.

Where I have specified a JSON cast on an attribute for the pivot model, I am finding that a string is returned (The JSON itself) when attempting to access that property.

Steps To Reproduce:

Network model

class Network extends Model
{
    public function clients()
    {
        return $this->belongsToMany(Client::class)
            ->using(ClientNetworkPivot::class)
            ->withPivot(['settings']);
    }
}

Client model

class Client extends Model
{
    public function network()
    {
        return $this->belongsToMany(Network::class)
            ->using(ClientNetworkPivot::class)
            ->withPivot(['settings']);
    }
}

Custom pivot model

class ClientNetworkPivot extends Pivot
{
    protected $casts = [
        'settings' => 'array'
    ];
}

Steps

$client = Client::find(1);

$networks = $client->networks;
foreach ($networks as $network) {
    var_dump(get_class($network->pivot), $network->pivot->settings);
}

Expected output

string(36) "App\Models\Pivots\ClientNetworkPivot"
array(0) {
}

Actual output

string(36) "App\Models\Pivots\ClientNetworkPivot"
string(2) "{}"

Additional Information

It seems that in this case, the attribute is being json_encoded again when it's being set in the pivot model. By running var_dump($network->pivot->getAttributes()['settings']); I am getting the following output string(4) ""{}""

#18149

@jrhenderson1988
Copy link
Contributor Author

jrhenderson1988 commented Feb 27, 2017

I did manage to work out a way to get around this by overriding the Pivot constructor and using the setRawAttributes method in place of the forceFill method. I'm not 100% sure if this may cause any unwanted side effects though.

class ClientNetworkPivot
{
    protected $casts = [
        'settings' => 'array'
    ];

    public function __construct(Model $parent, $attributes, $table, $exists = false)
    {
        $this->setConnection($parent->getConnectionName())
             ->setTable($table)
             ->setRawAttributes($attributes)
             ->syncOriginal();

        $this->parent = $parent;

        $this->exists = $exists;

        $this->timestamps = $this->hasTimestampAttributes();
    }
}

@jrhenderson1988
Copy link
Contributor Author

This issue has been fixed via #18127 and was released in 5.4.14.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant