Codeception: How to update a record in database?

Created on 6 May 2015  路  7Comments  路  Source: Codeception/Codeception

In the Laravel4 module there is the method haveInDatabase().
If you want to update a record but not create a new one how are you supposed to do?
I am aware of this closed issue https://github.com/Codeception/Codeception/issues/710 but it is pretty old and not explanatory. Googling for solutions doesn't help either.

Thanks!

Laravel4

Most helpful comment

this is what I ended up writing to get this to work. (Obviously not super secure, but seeing as it's just for tests it does not matter.)

/**
 * @param string $table
 * @param array $data in format [column => value, column2 => other value]
 * @param string $where ie. "ID = 99" or "my_column LIKE '%lala'"
 */
public function updateInDatabase($table, array $data, $where)
{
    $dbManager = $this->getModule('Db');
    $dbManager->_initialize();

    $set = [];
    foreach ($data as $column => $value) {
        $set[] = "`{$column}` = '{$value}'";
    }

    $query = sprintf("UPDATE %s SET %s WHERE %s", $table, implode(', ', $set), $where);

    $dbManager->driver->executeQuery($query, []);
}

All 7 comments

You cannot use the Laravel 4 module to update records in the database. If you really need that functionality you probably should create a helper method that does this.

Just out of curiosity, why do you need to update an existing record in your tests?

I am seeding my database at the beginning of my tests, and just need to update a value for a specific record for one of my test.

So I would have to use the Db module, extend it and add a method to update or you mean something else by helper?

You can find more about helpers in the documentation: http://codeception.com/docs/03-ModulesAndHelpers#Helpers.

In a helper you can execute any code you want. You could for example use Eloquent directly to update a database row:

$model = Model::find(1);
$model->update(['attribute' => 'value']);

Or you could access the Laravel DatabaseManager and do your updates through that:

$dbManager = $this->getModule('Laravel4')->grabService('db');
$dbManager->connection()->update(/*...*/);

My bad for not checking the documentation more thoroughly. I will give it a try. Will keep the issue opened until I have it working and will close after.

Worked fine. Thanks for the hint @janhenkgerritsen

this is what I ended up writing to get this to work. (Obviously not super secure, but seeing as it's just for tests it does not matter.)

/**
 * @param string $table
 * @param array $data in format [column => value, column2 => other value]
 * @param string $where ie. "ID = 99" or "my_column LIKE '%lala'"
 */
public function updateInDatabase($table, array $data, $where)
{
    $dbManager = $this->getModule('Db');
    $dbManager->_initialize();

    $set = [];
    foreach ($data as $column => $value) {
        $set[] = "`{$column}` = '{$value}'";
    }

    $query = sprintf("UPDATE %s SET %s WHERE %s", $table, implode(', ', $set), $where);

    $dbManager->driver->executeQuery($query, []);
}

Whoever is going to use the solution by @dwenaus, note that $dbManager->_initialize() will load your dump defined in codeception.yml at:

modules:
    config:
        Db:
            dump:

every time you do $I->updateInDatabase(). The fix for that is simple: just remove this line:

$dbManager->_initialize();

The module you get with $dbManager = $this->getModule('Db'); is probably already initialized.

Was this page helpful?
0 / 5 - 0 ratings