Robert Robert - 1 year ago 72
MySQL Question

How can I append an Eloquent property from a related model without getting the model's contents?

I have 2 eloquent models:




They are both related by user_id

I'm attempting to set up and appends attribute in the SharedEvents model that will append the full_name of the user with whom the event has been shared.

For the sake of readability, I'm only including the appends components of my class

class SharedEvents extends Model {

protected $appends = ['fullName'];

* @return BelongsTo
public function user() : BelongsTo {
return $this->belongsTo('Path\To\EloquentUser', 'shared_with_id', 'user_id');

* @return mixed
public function getFullNameAttribute(){
return $this->user->user_full_name;

Unfortunately when I run this I'm getting back both the full name and the entire user model when I only want the full name.

Is there a way to avoid attaching the content of the user model?

Answer Source

It feels like you're trying to make columns from your EloquentUser model first class citizens in your SharedEvent model. You're getting close, but consider...

When working with relationships, this is a good way to be explicit:

Assuming user_full_name is an accessor on your User model:

// EloquentUser.php

// This will automatically add your accessor to every query 
// as long as you select the columns the accessor is made 
// up of
protected $appends = ['user_full_name'];

 * User Full Name Accessor

 * @return string
public function getUserFullNameAttribute()
    return $this->first_name . ' ' . $this->last_name;

// SharedEvent.php

 * A SharedEvent belongs to an Eloquent User

 * @return BelongsTo
public function user() : BelongsTo 
    return $this->belongsTo('Path\To\EloquentUser', 'shared_with_id', 'user_id');

// Somewhere in your controller or wherever you want to access the data
$sharedEvents = SharedEvent::with(['user' => function ($query) {
    $query->select('user_id', 'first_name', 'last_name');
}])->where(...)->get(['shared_with_id', ...other columns]); // you must select the related column here

This should get you the closest to what you want, but there are a couple of things you should know:

  1. If user_full_name is an accessor, you need to select all of the columns that make up that accessor (as I mention above)
  2. You must select the related keys (user_id in EloquentUser and shared_with_id in SharedEvent)
  3. The $appends is necessary in EloquentUser here because you can't directly add an accessor to your sub query inside the closure.

Try to get comfortable with using a closure as the 2nd argument in your relationships. It's the best way to really be precise as to which columns you're selecting when you're loading relationships — Eloquent makes it really easy to be lazy and just do:


which as you've see will just do a select * on both SharedEvent and your user relationship.

Another thing I've noticed when working with complex queries that use relationships is that you can quickly reach a point where it feels like you're fighting the framework. That's often a sign to consider simplifying ot just using raw SQL. Eloquent is powerful, but is just another tool in your programming tool belt. Remember that you have other tools at your disposal.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download