Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I traverse through model relationships in laravel with dot syntax

I'm trying to traverse through complex eloquent model relationships/attributes, and I'd like to use a simple dot structure to iterate through this, similar to how you can traverse arrays with Arr::get()

Example:

$data = [
  'foo' => [
    'bar' => [
      'key' => 'value'
    ]
  ]
];
$value = Arr::get($data, 'foo.bar.key'); // returns 'value'

I've tried using

$value = Arr::get($model, 'relation.subrelation.attribute')

However this fails and aways returns null, even though eloquent models support ArrayAccess.

Does laravel have a simple way to accomplish this?

like image 507
Ben Rowe Avatar asked Nov 11 '15 06:11

Ben Rowe


People also ask

What is with () in Laravel?

with() function is used to eager load in Laravel. Unless of using 2 or more separate queries to fetch data from the database , we can use it with() method after the first command. It provides a better user experience as we do not have to wait for a longer period of time in fetching data from the database.

How do you define many relationships in Laravel?

As we have defined the hasMany relationship on Brand model which return the related records of Product model, we can define the inverse relationship on the Product model. Open your app/Product. php model file and add a new method called brand() in it which will return the related brand of a product.

What is BelongsTo in Laravel?

BelongsTo is a inverse of HasOne. We can define the inverse of a hasOne relationship using the belongsTo method. Take simple example with User and Phone models. I'm giving hasOne relation from User to Phone. class User extends Model { /** * Get the phone record associated with the user.


1 Answers

For all those wondering, I've managed to figure out a solution by modifying the arr::pull() function to work specifically with models:

public static function traverse($model, $key, $default = null)
{
    if (is_array($model)) {
        return Arr::get($model, $key, $default);
    }


    if (is_null($key)) {
        return $model;
    }

    if (isset($model[$key])) {
        return $model[$key];
    }

    foreach (explode('.', $key) as $segment) {
        try {
            $model = $model->$segment;
        } catch (\Exception $e) {
            return value($default);
        }
    }

    return $model;
}
like image 75
Ben Rowe Avatar answered Sep 18 '22 22:09

Ben Rowe