12

How can i call, from a Model, a function present in another model? I would like not to repeat code.

Mike
  • 530
  • 1
  • 7
  • 21
  • possible duplicate of [Can I use one model inside of a different model in CakePHP?](http://stackoverflow.com/questions/980556/can-i-use-one-model-inside-of-a-different-model-in-cakephp) – Hardik Sondagar Jul 15 '13 at 10:43

7 Answers7

18

We can use Model relation to call the function in another model. Eg.

$this->Model->ModelOne->find();
$this->Model->ModelOne->customFunc();

If there is no relation in the models, The we can use

$this->loadModel('ModelName');

To use in the model. In this case you can use

$this->ModelName->function();

directly as you've loaded that model.

Vins
  • 8,849
  • 4
  • 33
  • 53
  • 5
    Not sure using 'loadModel' is correct as of Cake 1.3, per [The loadModel function comes handy when you need to use a model which is not the controller's default model or its associated model.](http://book.cakephp.org/view/992/loadModel). To load a Model from a Model use [ClassRegistry::init](http://api13.cakephp.org/class/class-registry#method-ClassRegistryinit) – Aaron K Oct 25 '11 at 04:39
  • 4
    This does not work in cakephp 2.3 ( if loaded in a controller, ofc works, in model not ) – Igor L. Jul 23 '13 at 08:29
7

You should try to have relationships between your models. There are many types of relationships which you can read here...

If you have above said associations, you can access your associated models using:

$this->Model->OtherModel->function();

If your models are not related in any way, you should use:

ClassRegistry::init('OtherModel')->function();

You can check out my question on this where I obtained great answers

Community
  • 1
  • 1
AlexBrand
  • 11,971
  • 20
  • 87
  • 132
2

User App::import()

App::import('Model','OtherModel');
$attr = new OtherModel();
$attr->Othermodelfunction();
Hardik Sondagar
  • 4,347
  • 3
  • 28
  • 48
0

In 2.x versions the $this->Model1->Model2 syntax answered above will not work. Calling functions from another models in many cases is the job of a controller, not the model. Consider that, the model methods should be limited to querying and updating data whilst maintaining database integrity.

1st method: using the controller

I'll illustrate this with an example of Firm and User models, while Firm hasMany users. This method is recommended, if you plan to add extra controller functionality inbetween, such as setting flash messages or cookies.

User model:

public function saveRegisteredUsers($user_data,$firm_id){ ... }

--

FirmsController:

public function add(){
    if($this->Firm->save($this->request->data)){

    // set $this->Firm->id here 

    $this->loadModel('User');
    $this->User->saveRegisteredUsers($this->request->data['User'], 
      $this->Firm->id);

    // ... 

    }
}

2nd method: using the model

For this you will need to have correct model associations. The table names have to be users and firms conventionally. Following the terminology of the example above your relation should be defined as this in the Firm model:

public $hasMany = array( 'User' => array(
    'className' => 'User',
));

In the User model, you have to set up the belongsTo association properly:

public $belongsTo = array(
    'Firm' => array(
        'className' => 'Firm',
        'foreignKey' => 'firm_id',
        'dependent' => false
        )
    );

After this, you can call $this->User->saveRegisteredUsers() directly from any of the Firm model methods.

Rápli András
  • 3,869
  • 1
  • 35
  • 55
0

If you have a model function that you want to call from many models, the best approach is to abstract any references to the model name ($this->alias) and place the function in AppModel. Then it is accessible in any of your models.

class AppModel extends Model{
    public function myFunction($options = array(){
       do some stuff with $this->alias;
    }
}
DJ Far
  • 497
  • 5
  • 12
0
  • if there's a (direct or indirect) relationship between the model, you can call the function: $this->Model1->Model2->...->Modeln->function();

  • use bindModel

Anh Pham
  • 5,431
  • 3
  • 23
  • 27
0

no, you should use ClassRegistry like so:

    //MessagesController - in my send() method...

$this->set('content', ClassRegistry::init('Content')->find('first', array(
        'conditions' => array('Content.id' => 3)

        )));

NOTE:this is from my controller but I am pretty sure it works in model too.

Luke Barker
  • 915
  • 7
  • 14