Each YouTube video has four generated images. They are predictably formatted as follows:
https://img.youtube.com/vi/<insert-youtube-video-id-here>/0.jpg
https://img.youtube.com/vi/<insert-youtube-video-id-here>/1.jpg
https://img.youtube.com/vi/<insert-youtube-video-id-here>/2.jpg
https://img.youtube.com/vi/<insert-youtube-video-id-here>/3.jpg
The first one in the list is a full size image and others are thumbnail images. The default thumbnail image (i.e., one of 1.jpg
, 2.jpg
, 3.jpg
) is:
https://img.youtube.com/vi/<insert-youtube-video-id-here>/default.jpg
For the high quality version of the thumbnail use a URL similar to this:
https://img.youtube.com/vi/<insert-youtube-video-id-here>/hqdefault.jpg
There is also a medium quality version of the thumbnail, using a URL similar to the HQ:
https://img.youtube.com/vi/<insert-youtube-video-id-here>/mqdefault.jpg
For the standard definition version of the thumbnail, use a URL similar to this:
https://img.youtube.com/vi/<insert-youtube-video-id-here>/sddefault.jpg
For the maximum resolution version of the thumbnail use a URL similar to this:
https://img.youtube.com/vi/<insert-youtube-video-id-here>/maxresdefault.jpg
All of the above URLs are available over HTTP too. Additionally, the slightly shorter hostname i3.ytimg.com
works in place of img.youtube.com
in the example URLs above.
Alternatively, you can use the YouTube Data API (v3) to get thumbnail images.
The problem is caused by the fact that the Model
's toArray()
method ignores any accessors which do not directly relate to a column in the underlying table.
As Taylor Otwell mentioned here, "This is intentional and for performance reasons." However there is an easy way to achieve this:
class EventSession extends Eloquent {
protected $table = 'sessions';
protected $appends = array('availability');
public function getAvailabilityAttribute()
{
return $this->calculateAvailability();
}
}
Any attributes listed in the $appends property will automatically be included in the array or JSON form of the model, provided that you've added the appropriate accessor.
Old answer (for Laravel versions < 4.08):
The best solution that I've found is to override the toArray()
method and either explicity set the attribute:
class Book extends Eloquent {
protected $table = 'books';
public function toArray()
{
$array = parent::toArray();
$array['upper'] = $this->upper;
return $array;
}
public function getUpperAttribute()
{
return strtoupper($this->title);
}
}
or, if you have lots of custom accessors, loop through them all and apply them:
class Book extends Eloquent {
protected $table = 'books';
public function toArray()
{
$array = parent::toArray();
foreach ($this->getMutatedAttributes() as $key)
{
if ( ! array_key_exists($key, $array)) {
$array[$key] = $this->{$key};
}
}
return $array;
}
public function getUpperAttribute()
{
return strtoupper($this->title);
}
}
Best Answer
There was a commit submitted to the 4.0 branch made in August to add a reload() method, but so far it hasn't been merged with the newer Laravel branches.
But... Laravel 5 is providing a "fresh()" method that will return a new instance of the current model. Once you're using Laravel 5.0 or newer, you can reload a model like this:
Note that fresh() doesn't directly update your existing $model, it just returns a new instance, so that's why we need to use "$model = ". It also accepts a parameter which is an array of relations that you want it to eager load.
If you aren't yet using Laravel 5 but you want the same functionality, you can add this method to your model(s):
Update: If you're using Laravel 5.4.24 or newer, there is now a
$model->refresh()
method that you can use to refresh the object's attributes and relationships in place rather than fetching a new object likefresh()
does. See Jeff Puckett answer for more specifics on that.