-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[2.1.x] Uniqueness validator should convert values. #12005
Comments
Wait a minute ! Isn't that why we have |
That would not work if I want to have a custom validator that uses a |
Then just in this validator create datetime. Why beforeSave should be called if there is already beofreValidationOnSave ? Then both would to the same - call some function before save and validation. Also i don't understand this issue - you are telling that fix can be to call If you need BOTH string and datetime object then create as fields in class or something. Also how uniqueness validator is supposed to know how you want to convert those values to what ? Isn't getting all fields from metadata, checking their type if they date/datetime, converting datetime object to string just for uniqueness validation seriously break for SOLID ? |
I just found out that my fix wasn't actually working. Guess I had some source file not saved and thought it was working. I removed it from the issue. Let me rephrase completely, using an example from this documentation page. <?php
class Robots extends Model
{
public $id;
public $name;
public $status;
public function beforeSave()
{
// Convert the array into a string
$this->status = join(',', $this->status);
}
public function afterFetch()
{
// Convert the string to an array
$this->status = explode(',', $this->status);
}
public function afterSave()
{
// Convert the string to an array
$this->status = explode(',', $this->status);
}
} So if I create Now I want to do two validations (just something I made up):
For (1) I would write my own custom validator that accepts an array. I write this validator in a generic way, because I could also use it to validate a form or some other random value. In other words, the contract for this validator is that the input is always an array. For (2) I would like to use the Now I add both validators to to a validator, implement the
According to the example, this is how I should implement 'both fields'.
That's the problem I am looking a valid and generic solution for. I think the current implementation is limited for this problem.
Replace datetime with array and you have the same problem I described using a recommended example from the manual. |
We could just add $validator->add(
["name", "deleted"],
new Uniqueness([
"message" => "The name must be unique.",
"convert" => function($value) {
$value['deleted'] = $value['deleted']->format("Y-m-d H:i:s");
return $value;
}
])
); |
Awesome, that would definitely fix the problem while keeping everything at one place. I don't mind to implement this. Can do this on monday. |
Yea but it's kind of more changes then you think since validators are using some method from We should just get all values before starting the loop, and then in loop work on those values. Like before this loop - https://github.com/phalcon/cphalcon/blob/2.1.x/phalcon/validation/validator/uniqueness.zep#L109 create some array with values, bind our function to object, call it and set new values and work on those values in this loop from this line(so instead of |
Implement convert option to Uniqueness validator (#12005)
The Uniqueness validator executes a query on the database to see if it unique. But it uses the values from the model instance as-is. In my case, I convert high-level object to database-compatible values. For instance, I like to use
DateTime
, store 'structures' in JSON, and so on.In the example below, the Uniqueness validator builds a query using
$this->deleted
, which is still aDateTime
object becausebeforeSave
is not yet invoked. This makes the query invalid, because PHP cannot convert aDateTime
object into a string.The simple fix would be to call
beforeSave()
before all of the validations run. This would ensure that a query is build using the values that would otherwise be submitted to the database. But I don't want that, because it could break other validators (e.g. ones that DO expect richer objects). After all, the validation classes are generic and not explicitly bound to the ORM. I could use them for non-ORM things.Example model:
The text was updated successfully, but these errors were encountered: