Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

peanut's avatar

Laracasts Presenter - Relationships

I have my presenter looking like this:

<?php namespace Duplicolor\Presenters\Project;

use \Duplicolor\Presenters\BasePresenter;
use \Duplicolor\Models\Project\Post;
use \Config;
use \Str;
use \URL;

class PostPresenter extends BasePresenter {

    public function description_snip()
    {
        return substr($this->description, 0, 100);
    }

    public function thumbnail_image()
    {
        $post = new Post;

        return Config::get('app.url') . Config::get('app.projectPostPath') . $post->getThumbnail( $this->image );
    }

    public function edit_link()
    {
        return URL::to('garage/project/post/edit', array($this->projects->id, $this->id));
    }

    public function remove_link()
    {
        return URL::to('garage/project/post/remove', array($this->id));
    }

    public function view_link()
    {
        return URL::to('garage/project/post/view', array($this->id));
    }

    public function video_count()
    {
        return count($this->videos());
    }

}

I'm pulling my model like this:

$post = new Post;

My model looks like this:

<?php namespace Duplicolor\Models\Project;

use \Duplicolor\Models\Base;
use \Illuminate\Database\Eloquent\SoftDeletingTrait;
use \Config;
use \File;
use \Duplicolor\Helpers\Uploader;
use \Duplicolor\Models\Project\PostMedia;
use \Duplicolor\Models\Project\PostProduct;
use \Laracasts\Presenter\PresentableTrait;
use \Input;
use \Auth;

class Post extends Base {

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'project_posts';

    public static $rules = array(
        'project_id'      => 'required|exists:projects,id',
        'created_by'      => 'required|exists:users,id',
        'title'           => 'required|max:100',
        'description'     => 'required_if:image,null|max:2000',
        'image'           => 'required_if:description,null'
    );

    protected $fillable = array('title', 'description');

    use PresentableTrait;
    use SoftDeletingTrait;

    protected static $thumbnailWidth = 400;
    protected static $thumbnailHeight = 327;

    protected static $directory; // Directory for images

    protected $presenter = 'Duplicolor\Presenters\Project\PostPresenter';

    public function __construct(array $attributes = array())
    {
        parent::__construct($attributes);
        static::$directory = public_path() . Config::get('app.projectPostPath');
    }

    /****************
     * RELATIONSHIPS
    *****************/

    public function media()
    {
        return $this->hasMany('\Duplicolor\Models\Project\PostMedia', 'project_post_id');
    }

/****************
 * EAGER LOADING
*****************/
public function videos()
{
    return $this->media()
        ->select('id', 'url')
        ->whereType( 2 )
        ->get();
}

    /****************
     * QUERY SCOPES
    *****************/
    public function scopeTypicalColumns( $query )
    {
        return $query->select('id', 'title', 'description', 'image');
    }

    /****************
     * QUERIES
    *****************/
    public static function getByProjectId( $id )
    {
        return Post::whereProjectId( $id )
            ->typicalColumns()
            ->addSelect('project_id')
            ->with(array('projects' => function($query) {

                $query->select('id', 'title');

            }))
            ->orderBy('created_at', 'desc')
            ->get();
    }

    public static function getById( $id )
    {
        return Post::whereId( $id )
            ->first();
    }

}

So in my view I called

$post->present()->video_count.. but in the presenter, how I'm running $this->videos().. (this works fine in the view, but not when I move it to the presenter).. it shows this:

Call to undefined method Duplicolor\Presenters\Project\PostPresenter::videos()

But when I do a dd($post->videos()) where I pull my model it shows this:

object(Illuminate\Database\Eloquent\Collection)[421]
  protected 'items' => 
    array (size=0)
      empty

Why doesn't this work when I run these kinds of things in the presenter since it is suppose to be passing the Post object to it?

Thanks.

0 likes
3 replies
peanut's avatar

Thanks @Jeffrey! I thought I had it fixed, but nope. Always wondered this. That helps out a lot!

JeffreyWay's avatar

Yeah, right now, it's looking for a videos method on the presenter class, so you have to explicitly tell it to look on the entity.

I may change that; I think there's a pull request for it.

Please or to participate in this conversation.