2

I've 3 copies of my code - on development workstation, a test server and a production server.

Accordingly, I have 3 separate DB configs in the database.php file named dev, test & production.

I'm trying to figure out a way to switch the connection based on a value written to the Configure class. The way I'm trying to accomplish this out is to require a file called instance.php in the last line of bootstrap.php.

require( APP . 'Config/instance.php' );

My instance.php looks like:

<?php
// Configure instance type
Configure::write( 'InstanceType', 'Development' );
//Configure::write( 'InstanceType', 'Test' );
//Configure::write( 'InstanceType', 'Production' );

On the development workstation, the first line will be uncommented. Likewise on Test and Production the 2nd and 3rd lines will remain uncommented.

What I need is a method (perhaps in AppModel) that'll get executed before any other Model loads and will set the correct DB config. using the following code:

    // Set DB Config
    switch( Configure::read( 'InstanceType' ) ) {
        case 'Development':
            //default:
            $this->useDbConfig = 'default';
            break;
        case 'Test':
            $this->useDbConfig = 'test';
            break;
        case 'Production':
            $this->useDbConfig = 'production';
            break;
    }

OR (condensed version)

$this->useDbConfig = Configure::read( 'InstanceType' ) == 'Development' ? 'default' : strtolower( Configure::read( 'InstanceType' ) );

I tried to put this into a __construct() method inside AppModel but that started throwing a bunch of errors about missing arguments to __construct.

The outcome is to have:

  1. All models utilize the given DB connection.
  2. Not mess around with the DB specifier individually in each model.
  3. Not having to maintain 3 different copies of database.php on the 3 platforms.

How can I make this work?

Thank you.

1 Answer 1

2

You are on the right track. However, the code can't be placed in the construct for AppController.php.

Instead, add it to class DATABASE_CONFIG in /app/Config/database.php:

public function __construct() {
    // Set DB Config
    switch( Configure::read( 'InstanceType' ) ) {
        case 'Development':
            //default:
            //do nothing, as $this->default holds the right config
            break;
        case 'Test':
            $this->default = $this->test;
            break;
        case 'Production':
            $this->default = $this->production;
            break;
    }
}

Option 2: Symlinks

A different approach is to create 3 different versions of your database.php file, each holding the right database config for each server, which you maintain with the rest of your code.

/app/Config/database-development.php
/app/Config/database-test.php 
/app/Config/database-production.php 

These three files are copied over to all of your servers when you update the repositories.

You then create a symbolic link on each server pointing to the right config file:

// Development Server
ln -s app/Config/database-development.php app/Config/database.php 

// Test Server
ln -s app/Config/database-test.php app/Config/database.php 

// Production Server
ln -s app/Config/database-production.php app/Config/database.php 

Make sure this symlink is ignored in .gitignore, so it won't be overwritten (default CakePHP behaviour).

You still have to maintain 3 different database config files, but you do it locally. You can also get rid of Config/instance.php.

Sign up to request clarification or add additional context in comments.

1 Comment

inigo - thank you very much. Option 1 worked perfectly. Just what I was looking for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.