Welcome Guest, Not a member yet? Register   Sign In
Model within a model
#1

(This post was last modified: 06-29-2021, 12:32 PM by LuxesR.)

Is it possible to include a model in the '__construct' and do the same with the other model?

PHP Code:
class Users_model extends \App\Models\BaseModel {

    function __construct()
    {
        // Call the Model constructor
        parent::__construct();
 
$this->Settings model('Settings_model');
    }


PHP Code:
class Settings_model extends \App\Models\BaseModel {

    function __construct()
    {
        // Call the Model constructor
        parent::__construct();
 
$this->Users model('Users_model');
    }


When I do this, I always get a 503 Service Temporarily Unavailable error. Is there a workaround for this?
Reply
#2

Untested, but this should work:

PHP Code:
<?php

namespace App\Models;

use 
CodeIgniter\Model;
use 
App\Models\UserModel;


class 
LoggingModel extends Model
{

    public function __construct()
    {
        parent::__construct();
        $this->user = new UserModel();
    }

Reply
#3

Thanks for your response. But can I call the LoggingModel in the UserModel the same way?
Reply
#4

I can't think of any reason why not, have you tried? 

To match your model names:
PHP Code:
<?php

namespace App\Models;

use 
CodeIgniter\Model;
use 
App\Models\Settings_model;
class 
Users_model extends Model {

    function __construct()
    {
        // Call the Model constructor
        parent::__construct();
        $this->Settings = new Settings_model();
    }



PHP Code:
<?php

namespace App\Models;

use 
CodeIgniter\Model;
use 
App\Models\Users_model;
class 
Settings_model extends Model {

    function __construct()
    {
        // Call the Model constructor
        parent::__construct();
 
        $this->Users = new Users_model();
    }

Reply
#5

If each model is a dependency of the other and called in each constructor, there exists a cyclic dependency, or circular reference. You cannot do that. It will result to infinite recursion of Users model calling Settings model calling Users model calling Settings model and so forth.

From your current situation, your models are tightly coupled to each other. You should rethink ways to decouple your code.
Reply
#6

HINT: Like using a BaseModel and then extending all your models from the BaseModel.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#7

Thanks for your responses. What InsiteFX suggested was my first idea but I had the same problem with that. I'm using it like this (just like the Settings_model):

PHP Code:
namespace App\Models;
use 
CodeIgniter\Model;
class 
Users_model extends \App\Models\BaseModel {

    function 
__construct(){
        
// Call the Model constructor
        
parent::__construct();
    }


And my BaseModel looks like this:

PHP Code:
namespace App\Models;
use 
CodeIgniter\Model;
class 
BaseModel extends Model {

    public function 
__construct(){
        
$this->session = \Config\Services::session();
        
        
$this->Settings model('Settings_model');
        
$this->Users model('Users_model');
    }


So both have the Settings_model and the Users_model because they get it from the BaseModel. I thing this is getting the same error because it is the same idea of what paulbalandan is saying. Or maybe it is because I'm trying to fix my CI3 project in CI4, so it might has something to do that those models aren't correctly converted yet.

Are the examples above best practice or do I mis something?
Reply
#8

By any chance, why do you need an instance of Users model inside Settings model, and vice versa?
Reply
#9

(This post was last modified: 07-01-2021, 12:43 AM by paulkd. Edit Reason: add function for better clarity of purpose )

Hi, In general, I call models from controllers. However, here is an example where I've called Customers model from Orders model. Hope this helps.

Models/BaseModel.php
PHP Code:
<?php

namespace App\Models;

use 
CodeIgniter\Model;

class 
BaseModel extends Model
{
  protected $db;

  protected function __construct()
  {
    $this->db = \Config\Database::connect();
  

Models/Customers.php
PHP Code:
<?php

namespace App\Models;

use 
App\Models\BaseModel;

class 
Customers extends BaseModel
{
  protected $fields;

  public function __construct()
  {
    parent::__construct();
  }

  public function getCustomer(int $customerId)
  {
    $builder $this->db->table('customers c');
    $query $builder->select($this->fields['customers-all'])->where('c.id'$customerId)->get();
    return $query->getRowArray();
  

Models/Orders.php
PHP Code:
<?php

namespace App\Models;

use 
App\Models\BaseModel;

class 
Orders extends BaseModel
{
  protected $orderTable;
  protected $selectFields;

  public function __construct()
  {
    parent::__construct();
  }

  public function getOrder(int $orderId)
  {
    $c = new \App\Models\Customers;

    $query $this->orderTable->select($this->selectFields['all'])->where('o.id'$orderId)->get();

    $order $query->getRowArray();
    if (!$order) {
      return ['order' => $order];
    }

    $orderItems $this->getOrderItems($orderId);
    $customer $c->getCustomer($order['customer_id']);
    $address $c->getAddress($order['address_id']); 
Reply
#10

(06-30-2021, 07:07 PM)paulbalandan Wrote: By any chance, why do you need an instance of Users model inside Settings model, and vice versa?

Because in some functions of the Settings_model I need data from the users and in the Users_model I need data from the settings. That might not be best practice, but that's the situation.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB