user8517929
user8517929

Reputation:

Laravel belongs to many with additional methods

For followers relation on same User model I used belongsToMany()

public function followers() {
    return $this->belongsToMany('App\User', 'followers', 'follow_id', 'user_id');
}

But since I am using this for chat list on load with vue I am on page load passing json_encode(auth()->user()->followers) which works as I needed.

But when I am lets say using only some columns like:

->select(['id', 'name', 'avatar']);

I have additional method for avatar:

public function image() {
    return $this->avatar || 'some-default-image';
}

How can I pass that as well for each of many? Without withDefault method..

Upvotes: 0

Views: 174

Answers (2)

Eagle
Eagle

Reputation: 337

What you are looking for is the Accessor function:

Laravel Accessors and Mutators

Basically you define an accessor function in your model:

public function getAvatarAttribute($value)
{
    return $value || 'some-default-image';
}

Then when you access the avatar property using ->avatar, the accessor function will get called and you will get the computed value.

====================================================================

The comment has words limit.

You have followers table where each follower is a User. You use relationship to filter all followers which are a group of Users. You wanted getInfo() to be called on each follower so that the additional data is appended to your JSON structure.

In that case, you don't need to filter through each follower and call getInfo() yourself. You use accessor method, put your code in getInfo() into an accessor method, and modify $appends array in your User model, then then JSON data will be automatically appended.

public function getUserInfoAttribute()
{
    $userInfo = ... //use logic in your original getInfo method
    return $userInfo;
}

Then you add user_info into your User model's $appends array:

protected $appends = ['user_info'];

This way, your user_info will be automatically included when your instance is serialized into JSON.

Like I said in the comment, you should check out:

Appending Values To JSON

for more information.

As to APIs , whether you are using Vue or React or anything, when passing JSON data for your frontend code to consume, you are basically creating apis. FYI:

Eloquent: API Resources

Upvotes: 1

Vinay
Vinay

Reputation: 7674

Try adding this in your User model

class User extends Model {

    protected $appends = ['image'];

    // other stuff..
}

this will forcefully inject your computed property ie. image in every User model instance but for it work you have to name your method (or create another) like getImageAttribute()and not simply image()

// getter for `image` property in user model object
public function getImageAttribute() { 
    return $this->avatar || 'some-default-image';
}

Upvotes: 1

Related Questions