Amit Shah
Amit Shah

Reputation: 8179

Laravel: array to Model with relationship tree

I want to create an Eloquent Model from an Array() fetched from database which is already toArray() of some model stored in database. I am able to do that using this code:

$model = Admin::hydrate($notification->data);

$notification->data = [
  "name" => "abcd"
  "email" => "[email protected]"
  "verified" => 0
  "shopowner_id" => 1
  "id" => 86
  "shopowner" => [
    "id" => 1
    "name" => "Owner1"
    "email" => "[email protected]"
  ]
];

But i can't access the $model->shopowner->name I have to use $model->shopowner['name']

I want to use the same class of notification without any specific change to access the data.

Upvotes: 1

Views: 4097

Answers (5)

Amit Shah
Amit Shah

Reputation: 8179

Solution:

Thanks to @Devon & @Junas. by combining their code I landed to this solution

$data = $notification->data;                
$data['shopowner'] = (object) $data['shopowner'];
$model = Admin::hydrate([$data])[0];

Upvotes: 3

Jonas Staudenmeir
Jonas Staudenmeir

Reputation: 25906

If you want to access shopowner as a relationship, you have to hydrate it manually:

$data = $notification->data;
$model = Notification::hydrate([$data])[0];
$model->setRelation('shopowner', ShopOwner::hydrate([$data['shopowner']])[0]);

Upvotes: 4

Devon Bessemer
Devon Bessemer

Reputation: 35337

I see this as an invalid use of an ORM model. While you could mutate the array to fit your needs:

$notification->data['shopowner'] = (object) $notification->data['shopowner'];
$model = Admin::hydrate($notification->data);

Your model won't be functional because 'shopowner' will live as an attribute instead of a relationship, so when you try to use this model for anything other than retrieving data, it will cause an exception.

Upvotes: 1

cptnk
cptnk

Reputation: 2420

It has been a while since I used laravel but to my understanding once you use hydrate your getting a Illuminate\Database\Eloquent\Collection Object, which then holds Model classes.

These however could have attributes that are lazy loaded when nested.

Using the collections fresh method could help getting a Full database object as using load missing

Upvotes: 0

nakov
nakov

Reputation: 14278

You cannot access array data as object, what you can do is override the attribute and create an instance of the object in your model, so then you can use it like that. For example:

public function getShopownerAttribute($value)
{
   return new Notification($value); // or whatever object here
}

class Notification {

   public function __construct($data)
   {
      // here get the values from your array and make them as properties of the object
   }
}

Upvotes: 0

Related Questions