Closed xonipatino closed 2 years ago
Call dd($agent); after filling. The attributes and original properties must be the same.
I'm not sure this is a bug.
In the current implementation, it seems $attributes
has raw values from the database when fetched from the database.
https://github.com/codeigniter4/CodeIgniter4/blob/90eef161c1e7cb4af6165dfa87e8d4be074092fa/system/Database/MySQLi/Result.php#L144-L146
good morning friends, the validation problem still persists, I don't know if I managed to make myself understood with the error and if you can help me to give a solution.
What's the validation problem?
Hello everyone, look at the problem is the following:
When I send a POST form with the same information registered in the database, that is, without changes, it is supposed that when doing the validation with hasChanged() it should throw me False, because no change was made, this is not happening since the hasChanged() function takes the Status field (boolean) as if it always changed, but when I comment the Status field, that is, I don't add it in the Fill() function works correctly.
MySQL does not have a boolean data type. Any boolean value is converted to 1 or 0. MySQL php driver returns all data as a string. This means that the "status" field received from the database will have the value "1" or "0".
Here you convert the value to boolean
$status = (bool) $this->request->getPost("status", FILTER_UNSAFE_RAW);
$agent->fill([
//...
"status" => $status
]);
Can you guess what the result of the expression bool === string
will be?
@iRedds Thanks for your clarification, but in the model it returns an Entity (Agent_Entity), which converts this field (Status) into boolean, which I suppose hasChanged() will find of the same data type.
namespace App\Entities;
use CodeIgniter\Entity;
class Agent_Entity extends Entity
{
protected $attributes = [
..
..
"status" => true, //default in the DB table
"name" => null
];
protected $casts = [
..
..
"status" => "boolean",
"name" => "?string"
];
}
protected $returnType = \App\Entities\Agent_Entity::class
I performed the following validation before doing the fill() on the Controller and the result was True, this confirms that if there is any problem in the hasChanged()
$agent = model("agent_model")->find($_id); //this returns an Agent_Entity() echo gettype($agent->status); // this returned Boolean echo json_encode($agent->status === (bool) $status); // this returned True, This means that there are no changes, which is correct exit;
The "boolean" type casting only works for getting, not for setting. That is, when you call $agent->status That is, the original value does not change.
As I said above
Call dd($agent); after filling. The attributes and original properties must be the same.
hi @iRedds, You are right, I just assigned in the fill() the state with type string ("1" or "0") and it works correctly.
The code is as follows in the Controller:
$status= (bool) $this->request->getPost("status", FILTER_UNSAFE_RAW); //checkbox value, if checked is true, otherwise (null) is false
..
..
$agent = model("agent_model")->find($_id); //this returns an Agent_Entity()
..
..
$agent->fill([
..
..
"name" => $name,
"status" => ($status) ? "1" : "0"
]);
..
..
if ( $agent->hasChanged() ) { // this returned False, is correct!!
//send to save to database
}
...
Thank @iRedds, and thanks to all, I close the topic.
You can extend the CodeIgniter\Entity\Cast\BooleanCast
class by adding your own setter.
https://codeigniter.com/user_guide/models/entities.html#custom-casting
But the current behavior is difficult to understand, and inconsistent:
fill()
data, you have to use value from database ("1" or "0")
PHP Version
7.4
CodeIgniter4 Version
4.1.8
CodeIgniter4 Installation Method
Manual (zip or tar.gz)
Which operating systems have you tested for this bug?
Windows
Which server did you use?
apache
Database
MySQL 8.0.27
What happened?
I am currently working on a project where there is a boolean type column (state) in a table, I am working on this with an Entity, when I make a post to update a record in that table, I make the query with ->find() and I reassign the information of the inputs through the function ->fill(), example:
-- In Agent_Entity.php :
-- In Agent_Model.php :
-- In Agent_Controller.php :
When I call the function ->hasChange() making it ->fill() with the same data that is registered (without changes), ->hasChanged() always returns true, but when I comment it, it means:
sending the same registered information (without making changes) returns false. The error is in this latest version because this project was working very well in version 4.1.5 or 4.1.6 I don't remember which one it had
Steps to Reproduce
->hasChange() It must return false since sometimes changes are not made in the name or in the state and neither in the other fields.
Expected Output
false when there is no change even when a boolean field is included
Anything else?
No response