3

I am using Laravel 4.2.

I have two models: User and Video, both of these models are having one-to-many relationship i.e. User -> HasMany-> Video.

Recently, I got a requirement to display the list of users along with sum of file-size of total videos uploaded by each user and allow users to be order by the sum of file size ascending or descending.

I've made following changes in User model:

class User extends Eloquent {

    protected $hidden = array('videosSum');
    protected $appends = array('videos_size');

    public function videosSum() {
        return $this->hasOne('Video')
                    ->selectRaw('sum(file_size) as sum, user_id')
                    ->groupBy('user_id');
    }


    public function getVideosSizeAttribute()
    {
        // if relation is not loaded already, let's do it first
        if ( ! array_key_exists('videos_size', $this->relations)){
            $this->load('videosSum');  
        }

        $related = $this->getRelation('videosSum');
        return $this->attributes['videos_size'] = isset($related->sum) ? (int) $related->sum : 0;
    }
}

And using like:

User::where('id', '!=', Auth::user()->id);

I am getting the desired result.

But the problem is, I don't want the videos_size attribute everywhere, where the User model gets called. I want to set it dynamically.

I tried User::$appends = ['videos_size'] but it gives protected property cannot be set outsize of class error.

I also tried to make a method in User model which set the $appends if called, but it is also not working.

Can anybody help me how to enable the appends property dynamically?

Dev
  • 6,570
  • 10
  • 66
  • 112

1 Answers1

4

Laravel doesn't support this off the bat. my friend and I wrote this extention: Dynamically hide certain columns when returning an Eloquent object as JSON?

basically you have to override your models.php toArray() method as appended attributes get calculated when you ask for the model in json or array form. you can add to the trait that's in that link and use it or just put these methods in your respective model class.

public static function getStaticAppends() {
    return self::$_appends;
}

public static function setStaticAppends(array $value) {
    self::$_appends = $value;
    return self::$_appends;
}

public static function getDefaultAppends() {
    return with(new static)->getAppends();
}

public function getAppends(){
    return $this->appends;
}

public function toArray()    {
    if (self::getStaticAppends()) {
        $this->appends = self::getStaticAppends();
    }
    return parent::toArray();
}
Community
  • 1
  • 1
Cptmaxon
  • 505
  • 2
  • 12