• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Model Design Question

#1
Question 
Hello guys,

I have a question regarding the design of the application and/or database tables.

First, I have an (kind of) "abstract" class called AbstractClass where I define some variables and also a corresponding database table (having columns for the variables).

Here comes the problem: If I then extend a SubClass and add some "other child" variables how can I load the child class from the database having also the variables of the parent class? As far as I tried it is not possible to load datas from a database VIEW or am I wrong? 

My current approach is to connect to the database table of the child and "inner join" the parent table. But only the child variables are loaded into the child class object where as the "var_dump" of the database request gives me all columns of the JOIN.

Is there a mistake in my thought regarding the design or is this kind of situation not yet implemented? An similiar example is to have a variable as a custom class which needs to be loaded seperately as CI does not recognize it...

I can provide example code if the question is unclear or needs clarification.
Reply

#2
Hello IVlike,

This is not an easy task to manage Abstract/Concrete class/table.
I've created an ORM that manages it:
https://github.com/vmoulin78/concorde

Here is an example:
https://github.com/vmoulin78/demo-concorde-postgresql

As you can see on the CDM:
https://github.com/vmoulin78/demo-concor...er/CDM.png
there is an abstract table Person and two concrete tables Author and Commentator

and the code:
https://github.com/vmoulin78/demo-concor...roller.php
Author::find(1); (or Person::find(1); it's the same)
You get an object Author with the Author properties and the Person properties

If you have a question about creating the CDM, the SQL file for the database or about initializing the project, don't hesitate to post it here

Vincent
Reply

#3
Ok, but so to say there is no way to achieve this within CI..

@Vincent: Does you framework also work with CI4 as the documentation states CI3...
Reply

#4
Code examples would help, as I don’t fully understand what your trying to do.
Reply

#5
The Concorde Project is based on CodeIgniter 3, so it is stable and ready for production use.

The ORM is in the folder ./system/artefact

The framework has been improved:
  • Namespaces management
  • Global transaction system
  • Some helpers have been added or improved
Reply

#6
@vincent78 this is the CodeIgniter 4 forum.
Reply

#7
@MGatner:

Here is my abstract class:
PHP Code:
<?php

namespace App\Models;

class 
AbstractClass
{
    private $pId 0;
    private $name "";
    protected $table "parent";

    /**
     * @return int
     */
    public function getPId(): int
    
{
        return $this->pId;
    }

    /**
     * @param int $pId
     */
    public function setPId(int $pId): void
    
{
        $this->pId $pId;
    }

    /**
     * @return string
     */
    public function getName(): string
    
{
        return $this->name;
    }

    /**
     * @param string $name
     */
    public function setName(string $name): void
    
{
        $this->name $name;
    }

and my child class:
PHP Code:
<?php

namespace App\Models;

class 
SubClass extends AbstractClass
{
    protected $table "child";
    private $subvar "";
    private $f_parent 0;
    private $cId 0;

    /**
     * @return int
     */
    public function getCId(): int
    
{
        return $this->cId;
    }

    /**
     * @param int $cId
     */
    public function setCId(int $cId): void
    
{
        $this->cId $cId;
    }


    /**
     * @return string
     */
    public function getSubvar(): string
    
{
        return $this->subvar;
    }

    /**
     * @param string $subvar
     */
    public function setSubvar(string $subvar): void
    
{
        $this->subvar $subvar;
    }

    /**
     * @return int
     */
    public function getFParent(): int
    
{
        return $this->f_parent;
    }

    /**
     * @param int $f_parent
     */
    public function setFParent(int $f_parent): void
    
{
        $this->f_parent $f_parent;
    }


If I then load the child from the database only the child variables are set:

PHP Code:
$db = \Config\Database::connect();
$db1=$db->table($table);
$db1->join("parent""f_parent=pId");
$c $db1->get()->getCustomResultObject(SubClass::class);

array(
1) {
  [0]=>
  object(App\Models\SubClass)#76 (8) {
    ["table":protected]=>
    string(5"child"
    ["subvar":"App\Models\SubClass":private]=>
    string(5"child"
    ["f_parent":"App\Models\SubClass":private]=>
    string(1"1"
    ["cId":"App\Models\SubClass":private]=>
    string(1"1"
    ["pId":"App\Models\AbstractClass":private]=>
    int(0)
    ["name":"App\Models\AbstractClass":private]=>
    string(0""
    ["pId"]=>
    string(1"1"
    ["name"]=>
    string(6"Parent"
  }

Reply

#8
Mike I think I get what you are trying to do, and I'm also not sure why it isn't working. First off though I would recommend making these classes in the Entities folder for framework consistency. You can do whatever you want of course, but in Model-View-Controller the model handles loading data from the database (you're using the Builder class instead, which is fine) and then the returned results are Entities (which can be arrays, generic objects, or a custom object class like yours). Just a suggestion.
CustomResultObject should be setting a value for each field returned in the result set:
PHP Code:
foreach ($this->{$_data}[$i] as $key => $value)
{
    
$this->customResultObject[$className][$i]->$key $value;


So first thing I'd check is that your result actually has the data. Something like:
PHP Code:
var_dump($db1->get()->getResultArray()); 
Reply


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.