Search code examples
phplaravelormeloquentslim

Laravel Eloquent Model using multiple tables combined into one (no separate models)


I'm working on an REST API with Slim and Eloquent. I used Medoo DB before. It worked well, but i wanted to remove the static Schema and get more flexible.

I have a DB Table with product information. Problem is i have many more Tables with product information. These are not used for them selves, but only in combination with a product.

So it doesn't make sense to create Eloquent Relationship Classes and a Model for every Sub-Table because they will never be used on there own. It is in fact one table extended over multiple tables.

I know the best would be to change the DB structure and to create one big table, but i cannot do that right now.

So in Medoo i defined a schema Structure with all joinable Tables and a query selecting one product worked. Like i said i want to stay flexible and not define the schema inside the code, but at the moment i can only select data from the main table.

So here is only the Product Model:

<?php
namespace Product\Models;

use Interop\Container\ContainerInterface;
#use Medoo\Medoo;
use \Illuminate\Database\Query\Builder;
use \Illuminate\Database\Eloquent\Model as Model;
use \Illuminate\Database\Capsule\Manager;

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;


class Object extends Model
{
    protected $database;

    public function __construct($database)
    {           
        $this->setTable('product_objects');
        $this->database = $database;
    }

    public function getObjectById($id) {

        /*       
        $data = $this->database
            ->table('product_objects')
            ->get($columns)
            ->first()
            ;
        */

        $data = $this->find($id); // this works (with one table)


        // Throw error if no result found.
        if (empty($data)) {
            throw new \Exception('No object found', 400);
        }        

        return $data;
    }
}

// this was just a test
class Freetext extends Model
{
    protected $database;

    public function __construct($database)
    {           
        $this->setTable('product_freetext');
        $this->database = $database;
    }
}

Is it possible to do something like:

$data = $this->find($id)->product_freetext->product_table3->product_table4 ...

Solution

  • I solved it so far by inserting a scope method that joins the other tables. Maybe someone has a better way?

    public function scopeObjects($query) {
      return $query->join('product_freetext', 'product_freetext.oid', '=', 'product_objects.id');
    }
    

    and then

    $data = $this->objects()->find($id);