Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In CAKEPHP can we dynamically change the table linked to a particular model?

Suppose I have 2 identical table having same structure(Call it 'tableA' & 'tableB').

I want to save certain data on table 'A' and certain data on table 'B'.

NOW I want to use the same MODEL for both the table.

I want to change the table linked with the Model(say 'ModelM') to change dynamically based on condition at the controller.

e.g.


In controller:- //sample code

function saveProduct(){

    $this->loadModel('ModelM');

    if(condition){

        $this->ModelM->useTable = 'A';

    }else{

        $this->ModelM->useTable = 'B';

     }
     $this->ModelM->save($this->data);

}

ADDITION ON 14th JANUARY 2011

Following is the copy/paste of code I am working on:

function experiment(){

    $tableName = 'temp_table'.'1234';

    mysql_query('CREATE TABLE '.$tableName.' LIKE temp_home_masters');

    $sql = $this->createInsertQuery($new_arr,$tableName);

    $status = mysql_query($sql);

    if($status){
        echo "saved successfully";
    }else{
        echo "error";
    }

    $this->NewHomeMaster->setSource($tableName);//NewHomeMaster was previously attached to a different table , here I want to change the tableName the model linked with dynamically.Model 'NewHomeMaster' already exists and uses a table ...Here I am willing to link this model to the newly created tempory table.//

    $home_details=$this->paginate('NewHomeMaster',array($new_conditions));

    mysql_query('DROP table '.$tableName);

}

UNFORTUNATELY THIS DOES NOT WORK...

like image 291
Libu Avatar asked Jan 13 '11 14:01

Libu


2 Answers

I originally set out to figure a solution to your problem, but the more I think about it, I believe your logic is flawed.

I can see how the fact that the tables are similar or identical can lead you to the decision of using a single model to interact with both tables. However, when you look at a what a model is supposed to be (In CakePHP basically an interface to a table), it doesn't make sense to switch back and forth.

The CakePHP docs explain models like this:

In object-oriented programming a data model is an object that represents a "thing", like a car, a person, or a house.

In your example, you really have two separate "things" that look exactly the same. Therefore, they should have their own models.

If your models are really going to have the exact same methods, then "the CakePHP Way" would be to define a custom Behavior that encapsulates your shared methods. Then attach the behavior to both models.

Then you can load the model you need in the Controller condition:

private $DynamicModel;

public function saveProduct() {
    if (condition) {
        App::import('Model', 'ModelZ');
        $this->DynamicModel = new ModelZ;
    } else {
        App::import('Model', 'ModelY');
        $this->DynamicModel = new ModelY;
    }
    $this->DynamicModel->save($this->data);
}
like image 116
Stephen Avatar answered Oct 19 '22 01:10

Stephen


Do this on your controllers before filter function:

$this->CakePHPModelName->setSource('table_name');

This will use different table.

Source: http://www.mainelydesign.com/blog/view/changing-cakephps-model-usetable-on-fly

like image 32
Jsonras Avatar answered Oct 19 '22 02:10

Jsonras