doujie9252 2016-08-25 07:25 采纳率: 0%
浏览 10
已采纳

为什么在laravel中获取unAccessorized字段时需要Accessorized字段

Suppose I have a Homework Eloquent model like this :

class Homework extends Model
    {
        protected $primaryKey = 'homework_id';
        protected $dates      = ['deadline'];
        protected $appends    = ['deadline_picker'];

        protected $fillable = ['lesson_id', 'teacher', 'title', 'desc', 'deadline', 'address', 'size', 'type'];


        public function getDeadlineAttribute ($value)
        {
            return date('d/m/Y H:i', strtotime($value));
        }

        public function getDeadlinePickerAttribute ()
        {
             return date('l d F Y-H:i', strtotime($this->attributes['deadline']));
        }
}

As you see I define a new Accessor (deadline_picker) for deadline field.

Now I want to select only title of this model like this :

public function Homeworks ()
{
    $homeworks =
    Homework::where('deadline', '>=', Carbon::now())->get(['title']);

    return $homeworks;

    //return view('pages/homeworks', compact('homeworks'));
}

But after running above code, bellow error is shown:

ErrorException in Homework.php line 30:
Undefined index: deadline

Seems that in this case, getting deadline field in ->get(['title']); is required (means ->get(['title','deadline']);).

Why it happens?

  • 写回答

1条回答 默认 最新

  • duanduji2986 2016-08-25 08:03
    关注

    This is because you've only selected the title attribute out of the database, but your accessor is expecting deadline to always exist too. The reason for this is because when you're returning $homeworks out of your controller, Laravel is converting the models into json (or similar) using the ->toArray() or ->toJson() methods on your model, which is calling your accessor.

    You have 2 options, you can either always pull deadline out of the database reguardless of whether you actually want it or not, or you can add an is_null() check to your accessor, something similar to below

    public function getDeadlinePickerAttribute()
    {
        return is_null($this->deadline) ? null : date('l d F Y-H:i', strtotime($this->deadline));
    }
    

    Theres one more improvement you could make, as you've supplied the deadline attribute on the $dates property of your model, Eloquent will automatically convert this into a Carbon object allowing you to easily manipulate the date without using strtotime() or any of those nasty older date handling functions.

    public function getDeadlinePickerAttribute()
    {
        return $this->deadline instanceof Carbon ? $this->deadline->format('l d F Y-H:i') : null;
    }
    

    More on Carbon http://carbon.nesbot.com/ and date mutators https://laravel.com/docs/5.3/eloquent-mutators#date-mutators

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?