t0berius's avatar

including related accessor

Assuming the following code:

$latestOrder = Order::awaitingPayment()->select(['id', 'seller_id', 'product_id'])->with(['seller:id,name,slug,current_level'])->latest()->first()->append('seller.is_popular_seller')->toArray()

User:

public function getIsPopularSellerAttribute()
{
    return ($this->current_level >= 10) ? true : false;
}

How can I add is_popular_seller to the attributes of the returned model?

Using ->append('seller.is_popular_seller') won't work.

0 likes
12 replies
newbie360's avatar

i don't understand, in your query didn't find any about user, but this not the problem

you can call the accessor by relation if there any relation?

$a->relation->relation->user->is_popular_seller
t0berius's avatar

@newbie360

Here's the complete code:

    //update latestOrders
    Cache::put('latestOrder', Order::awaitingPayment()
        ->select(['id', 'seller_id', 'product_id'])->with(['seller:id,name,slug,current_level'])
        ->latest()->first()->append(['is_popular_seller'])->toArray()
    , 300);

Now I want to make sure the is_popular_seller accessor is included. The accessor is defined on the seller relation, seller returns a user model.

Because I want to store the data as an array inside the cache cannot use model relations like mentioned by @newbie360 .

newbie360's avatar

can you show the Order and Seller model code

newbie360's avatar

hmmm actually i don't know how to explain about accessor, so if i'm wrong, correct me

Accessor is not a real column, in normal case it Only represent in response

just make a simple test: put this code in any model

protected $appends = ['hello_kitty'];

public function getHelloKittyAttribute()
{
    return 'Hello guys.';
}

Case 1: 'hello_kitty' is not represent

dd($post);

Case 2: 'hello_kitty' is represent

return $post;

Case 3: dynamic append

// protected $appends = ['hello_kitty'];

$post->append(['hello_kitty'])->toArray();

dd($post); // 'hello_kitty' is not represent

return $post; // 'hello_kitty' is represent

Case 4: dynamic append, asign to a variable

// protected $appends = ['hello_kitty'];

$post = $post->append(['hello_kitty'])->toArray();

dd($post);    // 'hello_kitty' is represent
return $post; // 'hello_kitty' is represent
t0berius's avatar

@newbie360

Order model:

public function seller(){

    return $this->belongsTo('App\User', 'seller_id', 'id');
}

Accessor (part of user model)

public function getIsPopularSellerAttribute(){

    return ($this->current_level >= 10) ? true : false;
}

I think you understand the problem now.

newbie360's avatar

oops this make me confuse, method name should be user ?

public function seller(){

public function user(){

in your User model use

protected $appends = ['is_popular_seller'];

public function getIsPopularSellerAttribute(){

    return $this->current_level >= 10; // already return bool here
}

and change

$latestOrder = Order::awaitingPayment()
        ->select(['id', 'seller_id', 'product_id'])
        ->with(['seller:id,name,slug,current_level'])
        ->latest()
        ->first()
        ->toArray();

dd($latestOrder);
Cache::put('latestOrder', $latestOrder, 300);

i guess this should work, but you already get the current_level by relation, why still need accessor?

t0berius's avatar

@newbie360 I only want the accessor to be connected / loaded this time, is there any way I can load it dynamically only this time?

I think you understand what I mean by loading related accessor (related because it's not part of the order model).

newbie360's avatar

if you need dynamically, find a collection helper to mount a new attribute name to $latestOrder->seller->is_popular_seller

since the accessor is simple return bool, may be not cause performance leak

and you get the level already

->with(['seller:id,name,slug,current_level'])

just use it, not really need the accessor
t0berius's avatar

@newbie360

The data is stored as array in cache, it is not possible to use the accessor at a later moment (when value is read from cache).

Any idea how I can put the insert of a new element inside the collection inside the existing closure?

newbie360's avatar

may be this work, since i don't have data for test

$latestOrder = Order::awaitingPayment()
        ->select(['id', 'seller_id', 'product_id'])
        ->with(['seller:id,name,slug,current_level', 'isPopularSeller'])
        ->latest()
        ->first()
        ->toArray();

dd($latestOrder);
Cache::put('latestOrder', $latestOrder, 300);

Order model use

public function seller()
{
    return $this->belongsTo('App\User', 'seller_id', 'id');
}

public function isPopularSeller()
{
    return $this->seller()->selectRaw('id, current_level >= 10 as is_popular_seller');
}

nothing added in User model !!

Please or to participate in this conversation.