40

I was wondering how to always append some data to Eloquent model without the need of asking for it for example when getting Posts form database I want to append the user info for each user as:

{
    id: 1
    title: "My Post Title"
    body: "Some text"
    created_at: "2-28-2016"
    user:{
            id: 1,
            name: "john smith",
            email: "example@mail.com"
         }
}
Mustafa Dwaikat
  • 3,392
  • 9
  • 27
  • 41

4 Answers4

80

After some search I found that you simply need to add the attribute you wants to the $appends array in your Eloquent Model:

 protected $appends = ['user'];

Update: If the attribute exists in the database you can just use protected $with= ['user']; according to David Barker's comment below

Then create an Accessor as:

public function getUserAttribute()
{

    return $this->user();

}

This way you always will have the user object for each post available as:

{
    id: 1
    title: "My Post Title"
    body: "Some text"
    created_at: "2-28-2016"
    user:{
            id: 1,
            name: "john smith",
            email: "example@mail.com"
         }
}
Community
  • 1
  • 1
Mustafa Dwaikat
  • 3,392
  • 9
  • 27
  • 41
  • 6
    Your use case is a bit wierd as a relationship with `User` would make `$model->user` available to you without needing to use appends. Also when the model is converted to JSON or cast to array, the `user` key would exist if you had loaded in that relationship. If you always want the user add `protected $with = ['user'];` to the model. – David Barker Feb 29 '16 at 14:22
  • yes that right with your way I always have to use `$model->user` but what I needed to have the user object without manually asking for it in addition I don't wanna go through a loop and I'm using it in an API so I can't get those when I'm displaying a list of articles. this way the user object will always automatically be available to you. – Mustafa Dwaikat Feb 29 '16 at 14:29
  • 6
    No, not when you add `protected $with = ['user']` it will be loaded automatically for you when you get the model. Appends is for when you want data that is not available in the database on your model. – David Barker Feb 29 '16 at 14:35
  • Oh.. I didn't know about that. I will check it out and update my answer. Thanks a lot. – Mustafa Dwaikat Feb 29 '16 at 15:08
  • 1
    There is a package to automatically append accessors to response https://github.com/topclaudy/eloquent-auto-append – topclaudy Dec 15 '18 at 17:35
  • Nice but how remove $appends from result? – Čamo Jun 08 '23 at 12:43
12

I found this concept is interesting, I learn and share things. Here in this example, I append id_hash variable which then converted into method by this logic.

It takes first char and converts into upper case i.e. Id and letter after underscore to uppercase i.e. Hash.

Laravel itself add get and Attribute to combine all together it gives getIdHashAttribute()

class ProductDetail extends Model
{
    protected $fillable = ['product_id','attributes','discount','stock','price','images'];
    protected $appends = ['id_hash'];


    public function productInfo()
    {
        return $this->hasOne('App\Product','id','product_id');
    }

    public function getIdHashAttribute(){
        return Crypt::encrypt($this->product_id);
    }
}

To simplify things append variable would be like this

protected $appends = ['id_hash','test_var'];

The method would be defined in the model like this

 public function getTestVarAttribute(){
        return "Hello world!";
    }
Hemant Kumar
  • 1,025
  • 15
  • 32
0

For example in the model:

protected $appends = [
    'mobile_with_code',
];

public function getFormattedMobileAttribute() {
    if (!$this->calling_code) {
        return $this->mobile;
    }

    return $this->calling_code . '-' . $this->mobile;
}

You can use it with the object normally.

In view:

{{mobile_with_code}}
  • You're appending `mobile_with_code` but your function is not named `getMobileWithCode`. I think you'd either need to rename your append or your function. – Whipenstein Jul 04 '23 at 18:49
0

Your database table is incorrect, you dont need to append anything it can be loaded using relationships:

first your post table should have user_id column which refer to your user table id column: { id: 1 user_id: 1 title: "My Post Title" body: "Some text" created_at: "2-28-2016" }

then in your post model you to have to define relationship based on your user_id:

public function user() {
    return $this->belongsTo("App\Models\User", "user_id");
}

then in your get api call all you have to do is load this relationship using: e.g. Posts::with("user")->get();