zen of coding

Changing model's table from the controller

For one reason, or another you might wish to change your Model’s table on the fly…

It would seem that it should be quite easy to do with:


$this->Company->useTable = ‘another_company_table’;

…but it’s not going to work…

Instead, in your controller, use:


$this->Company->table = ‘another_company_table’;

I haven’t checked to see why this works the way it does, so if someone has an explanation, I’ll gladly update the post with your insight.

P.S. Phally pointed out that it is better is use the wrapper for setting the table variable (always better than setting vars directly), like so: $this->Company->setSource(‘another_company_table’);

  • Phally

    I used this and it works, it is probably a wrapper:

    $this->Company->setSource('another_company_table');

    I got it from AD7six.

  • @Phally

    Yep, thanks.

  • keymaster

    Why would you want to change your model’s table?

  • @keymaster

    I would not, but there are case where someone would… Perhaps based on the logged in user (tracking).
    Or if you have a middle-tier system that requires dynamic table switching, there are certain scenarios where this could be useful.

    Just showing the available option, how it’s used… well that’s, up to the developer.

  • Phally

    @keymaster

    I used it to get data from a remote database where the tablename came from the local database. So I had a Remote model which changes tablename.

  • MistaJJ

    Wow Phally, you are amazing!

  • @MistaJJ

    :)

  • For a completely dynmic table with an unusual table name (eg. ‘results_1’) I found it to be working only when setting both properties.

    $this->Company->useTable = ‘another_company_table’;
    $this->Company->table = ‘another_company_table’;

    But then it worked even inside the model!

    Thank you for this hint – will save lots of time for the future!

  • @Deckard

    Thanks for sharing, that’s an interesting observation.

  • thanks teknoid

    this is what i need

    i need a code that can change table for my multilanguage site

    example

    en_contents for english content
    nl_content for dutch content

    but only use one model

    class Contents extends AppModel
    {
     $useTable = "en_contents"; //for default language
    }

    and for controller

    class ContentsController extends AppController
    {

     var $use = array('Content');

     function get($lang)
     {

      if($lang == 'nl') :

       $this->Content->setSource('nl_contents');

      endif;


    }
    }
  • @empe

    Cool, thanks for sharing… have you tried the translate behavior, seems like it would do what you are after more efficiently. Unless you have a legacy DB to work with.

  • Thanks!

    @teknoid. I plan on using this feature for a multi-tenant type web app that will segregate each users data into separate tables. Great Thanks!

    @phally. Thanks for the available options.

  • teknoid

    @Geoff Douglas

    You are certainly welcome, but I hope you are not the same person from cake’s IRC chat today, whom everyone tried to talk out of this approach to data modeling :)

  • Krzychu

    This way of changing model’s table is certainly great, but doesn’t seem to work when you have associations in your model. I mean – you have to set some table before you create associations. That’s why you cannot initialize $useTable as false and set it in the beforeFilter of your controller.

  • anas

    Is it possible to set default values for MySQL columns in CakePHP? I have access default value for user table as:

    $fields = $this->User->schema();
    $defaultValue = $fields[‘Amount’][‘default’];

    Now I want to change this default value to any particular value provided by admin .. Is it possible ?

    I have tried :

    $fields[‘Amount’][‘default’] = 500;

    $this->User->setSource($fields);

    But it not working .. promting me error .. cam any body help

  • teknoid

    @anas

    Why not set default in the DB?

    … but if you would like to do in the app, it is best done in beforeSave()

    function beforeSave() {

    $this->data[$this->alias][‘default’] = 500;

    return true;
    }

%d bloggers like this: