codeigniter4 / CodeIgniter4

Open Source PHP Framework (originally from EllisLab)
https://codeigniter.com/
MIT License
5.35k stars 1.9k forks source link

Bug: Database connection #3043

Closed antevidovic385 closed 4 years ago

antevidovic385 commented 4 years ago

Describe the bug This is problem in DEVELOPMENT environment in app that use multiple database. I try to insert record in other database table (not default) and insert failed when I use is unique validation rule 'name' => 'required|is_unique[' . $this->table . '.name], set up on model.

During the validation process is used default DB-group, not custom that is set $this->db = \Config\Database::connect('custom_database);.

bug_validation_on_default

database_group

This problem does not appear on production and testing environment or on dev env when I don't use unique validation rule

CodeIgniter 4 version CI 4

Expected behavior, and steps to reproduce if appropriate I expected that the record will be insert in custom database table

Context

lonnieezell commented 4 years ago

How are you handling validation? In the controller, or automatically in the model?

The model should automatically handle it. If doing it in the controller, it has no way to know, so you have to explicitly tell it so. Looks like we could add a parameter to the Controller's validate method for that, though.

In the meantime, you can always run validation manually in a controller, passing in the database group to the run method.

antevidovic385 commented 4 years ago

Validation is handle on model.

I have user model that is subclass of abstract class. (Class RoleModel extends AbstractCrud{...}) Abstract class is subclass of CI model class (CodeIgniter\Model). (abstract class AbstractCrud extends Model{..})

In user model and abstract class I called parent::__construct(); in constructot. In that case CI4 did zigzag with db groups (default custom). That (in combination with is_unique) produced err that table in default db does not exist. zig_tag_db

0 /var/www/html/app_folder/vendor/codeigniter4/framework/system/Database/MySQLi/Connection.php(331): mysqli->query()

1 /var/www/html/app_folder/vendor/codeigniter4/framework/system/Database/BaseConnection.php(738): CodeIgniter\Database\MySQLi\Connection->execute()

2 /var/www/html/app_folder/vendor/codeigniter4/framework/system/Database/BaseConnection.php(666): CodeIgniter\Database\BaseConnection->simpleQuery()

3 /var/www/html/app_folder/vendor/codeigniter4/framework/system/Database/BaseBuilder.php(1845): CodeIgniter\Database\BaseConnection->query()

4 /var/www/html/app_folder/vendor/codeigniter4/framework/system/Validation/Rules.php(234): CodeIgniter\Database\BaseBuilder->get()

5 /var/www/html/app_folder/vendor/codeigniter4/framework/system/Validation/Validation.php(294): CodeIgniter\Validation\Rules->is_unique()

6 /var/www/html/app_folder/vendor/codeigniter4/framework/system/Validation/Validation.php(189): CodeIgniter\Validation\Validation->processRules()

7 /var/www/html/app_folder/vendor/codeigniter4/framework/system/Model.php(1443): CodeIgniter\Validation\Validation->run()

8 /var/www/html/app_folder/vendor/codeigniter4/framework/system/Model.php(701): CodeIgniter\Model->validate()

9 /var/www/html/app_folder/app/AbstractExtension/AbstractCrud.php(28): CodeIgniter\Model->insert()

....

When I call parent::construct(); only in user model (or abstract class) or in case whitout calling parent::construct();, I get this err

err_2

Only case when everything is OK is when I don't call methods in abstract class.

By my opinion, problem is that CI returns errors in case of this architecture (model has parent class, parent class is subclass of CI model class (CodeIgniter\Model)) if working with multiple database

antevidovic385 commented 4 years ago

I solved my problem on this way: public function construct() { if (ENVIRONMENT !== 'testing') { $this->DBGroup = 'CUSTOM DB GROP'; // $this->setDatabase(); // $this->db = \Config\Database::connect($this->getDatabase()); } parent::construct(); }

Set DBGroup not $this->db = \Config\Database::connect('CUSTOM DB GROP');

arnoldsmyth commented 3 years ago

I believe that this is still a bug. The following code generates a Unable to connect to the database. error with the validation in place. If I change the connection to $db = db_connect(); it works perfectly. If I remove $model->setValidationRules($validationRules); it works fine - but obviously does not validate.

$db = db_connect('live'); $model = model('UserModel', true, $db); $validationRules = [ 'first_name' => 'required', 'last_name' => 'required', 'email' => 'required|valid_email|is_unique[users.email]', 'password' => 'required|min_length[8]', 'password_confirmation' => 'required_with[password]|matches[password]' ]; $model->setValidationRules($validationRules); $data = [ 'first_name' => $this->request->getVar('first_name'), 'last_name' => $this->request->getVar('last_name'), 'email' => $this->request->getVar('email'), 'password' => $this->request->getVar('password'), 'password_confirmation' => $this->request->getVar('password_confirmation') ]; $id = $model->save($data);