vkronlein
341
10
Laravel

How Are Models Called Statically

Posted 2 years ago by vkronlein

I've looked all through the Eloquent classes and I can't figure out how Models are built so that they can be called statically.

The reason I ask is that I want to build that functionality into my Base\Repository class so that I can call them in the same manner as Models can be called.

use App\Repositories\OrderRepository;

class OrderController extends Controller
{
    public function index()
    {
        $orders = OrderRepository::with('receipts')->get();
    }
}

My base repository class looks like so:

<?php 

namespace App\Base;

use Illuminate\Container\Container;
use Illuminate\Database\Eloquent\Model;

/**
 * App abstract for respositories to extend.
 */
abstract class Repository
{
    /**
     * Local application instance.
     * 
     * @var $app
     */
    private $app;

    /**
     * Local model instance.
     * 
     * @var $model
     */
    protected $model;

    /**
     * Create a new repository instance.
     * 
     * @param \Illuminate\Container\Container
     * @param Collection $collection
     */
    public function __construct()
    {
        $this->app = new Container();
        $this->makeModel();
    }

    /**
     * Specify Model class name
     *
     * @return mixed
     */
    public abstract function model();

    /**
     * Create a new model instance.
     * 
     * @return \Illuminate\Database\Eloquent\Builder
     * @throws Exception
     */
    public function makeModel()
    {
        $model = $this->app->make($this->model());

        if (!$model instanceof Model) {
            throw new Exception("Class {$this->model()} must be an instance of Illuminate\\Database\\Eloquent\\Model");
        }

        return $this->model = $model;
    }

    /**
     * call the function of repository
     */
    public function __call($method, $args)
    {
        return call_user_func_array([$this->model, $method], $args);
    }

    /**
     * Execute the create method on the model.
     * 
     * @param array $data
     * @return bool
     */
    public function create($data)
    {
        return $this->model->create($data);
    }

    /**
     * Execute the update method on the model.
     * 
     * @param array $data
     * @param string|int $id
     * @param string $attribute
     * @return mixed
     */
    public function update($id, $data, $attribute = 'id')
    {
        $record = $this->model->where($attribute, $id)->first();
        $record->fill($data);

        return $record->save();
    }

    /**
     * Execute the delete method on the model.
     * 
     * @param string|int $id
     * @param string $attribute
     * @return mixed
     */
    public function delete($id, $attribute = 'id')
    {
        $record = $this->model->where($attribute, '=', $id)->first();
        
        return $record->forceDelete();
    }
}

I'm assuming that I should be able to create a static instance of the repo in some way that would access the model, but I'm not sure how to do that.

Please sign in or create an account to participate in this conversation.

Reply to

Use Markdown with GitHub-flavored code blocks.