开发者

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

开发者 https://www.devze.com 2023-02-05 00:54 出处:网络
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\'.

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...


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);
}


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


The situation is tricky, as Stephen describes it, because your approach somewhat violates the MVC conventions.

However, if you're willing to go to the dark side of custom hacks, you could consider creating you own customized Datasource in CakePHP that handles this kind of logic for you. An option is to extend a given Datasource (presumably the MySQL one) with you own custom logic that aims to perform some prelimary filtering/conditioning before interacting with the database. Not that clean because the logic is placed in the wrong scope, but could work. Have a look here for a start: http://book.cakephp.org/view/1075/DataSources

Alternatively, you could create two different models and make them share the same logic using a behavior. This kinda limits you to take the choice of model earlier in the flow (and thus doesn't only affect the location of data storage), but might be a possibility.

0

精彩评论

暂无评论...
验证码 换一张
取 消