-
-
Notifications
You must be signed in to change notification settings - Fork 38
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
Update method rules() in next versions. #1
Comments
That's quite similar to schema builder used in migrations. I like the idea. |
Would you like to implement it? |
What is login in $this->login ? New object variable needed to be defined? |
@mgrechanik class SomeModel
{
public $property1;
public $property2;
# variant #1
public function rules()
{
return [
$this->property1 => Validator::required()->string()->min(6)->max(255),
$this->property2 => Validator::required()->string()->min(6)->max(255)
];
}
# variant #2
public function rules()
{
[$this->property1, $this->property2] => Validator::required()->string()->min(6)->max(255)
}
} |
@samdark |
I am. |
I like the idea but don't you think about something like:
|
@bizley can be and so ) |
I do like the idea to use builder pattern to configure validators - the current strings array is error prone and devs have to always check documentation of the correct validator shortcut (was it However, I wouldn't like to have to define same rule for multiple fields like this: # variant #1
public function rules()
{
return [
$this->property1 => Validator::required()->string()->min(6)->max(255),
$this->property2 => Validator::required()->string()->min(6)->max(255)
];
} And it's a bit hard to imagine how the implementation of Variant #2 would look like, besides the fact that this seems like a confusing way to combine In the simplest form, we could just preserve the field definition and opt for builder pattern for the validators. Eg: public function rules()
{
return [
[['property1', 'property2'], Validator::required()->build()],
['property2' => Validator::string()->min(6)->max(255)->build()],
];
} With this, we could allow combining validators for a field in a more obvious manner: public function rules()
{
return [
['property2' => Validator::composite()
->add(Validator::required())
->add(Validator::string()->min(6)->max(255)->when(function (SomeModel $model) {
return $model->property3 === "awesome";
}))
->build()
],
];
} What do you think? |
@ddinchev oh shit, it's crazy. Cool. It's will be difficult to write something this (for me). And has a one question - what do we do with previous versions? More projects use current rules. I think it not good to crash them, when they updated. I think we can save current syntax and add something new. Maybe, new method? Or add some 100+ if() to code ?) UPD: for difficult conditions, I think, we can use custom class that will be extends like a \yii\validators\Validator |
Well, Yii 2.1 is going to have many breaking changes, this is up to @samdark and the team behind Yii2 to decide. We could have detection if the new pattern is used or the old definition, and let the framework handle both, and maybe remove the old syntax in v2.2. |
@ddinchev and it will we awesome decision! |
It looks like overkill to me. You're trying to create sophisticated syntax to configure object (validator). Why not create object directly? public function rules()
{
return [
[['login', 'pass'], new StringValidator(['min' => 0, 'max' => 100])],
// with fluent setters
[['login', 'pass'], (new StringValidator())->min(6)->max(255)],
];
} It should be more intuitive, more flexible (works with custom validators), easier to implement and does not conflict with current syntax, so we could keep BC and support both syntax without much effort. |
@rob006 not a bad thought 👍 |
@rob006 it's maybe confusing to me because right now If that is just a copy/paste error and you don't intend to combine |
I have an idea to add some ValidatorHelper || ValidationBuilder that replaced your builder syntax to current syntax. Good? Bad? How example: <?php
class ExperementalValidator
{
public static function required()
{
return 'required';
}
public static function min(int $min)
{
return ['min' => $min];
}
} |
@ddinchev I fixed my example - it was dump copy-paste :) |
Hey, guys, I made some wrapper on current rules. What do you think? https://github.com/Auramel/yii2-validation-rules. See ValidationRule.php PHPDoc. Example in it. It has a new syntax and not crash old. Perfect? UPD: Has idea to call method |
@samdark will this be implemented? And in which form? I like this variant the most. |
Me too. |
Will this chained calls slower then simple array of rules data? Even if a lot of objects? |
Should not. |
I can make simple tests to show performance of both the variants. But first we need to finish our discussion about the final syntax in #108. |
AFAIK validator object will be created from array anyway, so there should be no difference in performance. Especially on PHP7. |
I think it's a good idea to make a separate module for this functionality, e.g. Minuses:
Pluses:
WDYT? I think I'll make some free time for this in a month. |
I agree. Validation could be separate library. |
@miolae let's design it first though before implementing it. Would you please make a draft document explaining concepts about how to use it, where to use it, what are dependencies etc.? |
Yes, I'll do this, but after some higher priority things are completed. I'm going to show this draft in late march or april. |
@viktorprogger "Validation" of request and permissions is middlewares job, not validators. Decoupling validators from models may be good move, but using it in controller in this way is terrible example. |
It's reasonable |
I'll make another example later :) |
Here is a new draft of the library itself. It's not finished yet, it's just to show the way I see it. Feel free to ask anything or to give an advise. |
I've added a readme file with concept describing and usage examples. If anybody needs it to be complemented - feel free to say me what to write there. I've found a couple of bad places in this draft during creating the readme.
|
To implement the rules of validation of business models with a large number of fields, the old syntax is much shorter, efficient and self-desciptive: ['views', 'trim'],
['views', 'default', 'value' => 0],
['views', 'integer', 'min' => 0, 'max' => 65535],
['views', 'filter', 'filter' => 'intval'], then new StringValidator(['min' => 0, 'max' => 100])]
$this->validator->getFactory()->get(StringValidator::class, ['min' => 0, 'max' => 100])] |
The old syntax is still possible, I've kept it. |
About option №1: I'm inclined to opinion to add magic configuration through constructor to the |
Interface should not care about configuration. |
IMO requiring library for this is not a problem, but using |
It's decoupling of classes and dividing responsibility.
Maybe it's a naming problem. If you have an idea about more clear naming - lets discuss it. |
Do we need it if we require to create return [
['name', new RequireValidator()],
['email', new EmailValiadtor()],
]; |
We allow to do so, not require. The preferred way is to create rules through DI container either using their string aliases (e.g. 'require' and 'email'), or instantiating them with DI container like in the last example in this comment. |
Why? If AR relies on specific implementation of validator, then changing it by DI container will change how AR works. IMO DI should not change business logic in this way. Besides, you didn't answer my question. :P |
If smthng relies on specific implementation, it must use this specific implementation, not some contract through DI. But if you has 10-20 places of email validation in your project (by standard yii validator), and suddenly a business task to change this validation appeared, it could be cool just to set your own email validator implementation through di ( The factory is really useless in case when validation rule instances are created in-place. It's created to cover all other cases.
I answered as I see)) Could you please repeat it in other words? |
That is my point - validation is internal logic of model, you should not rely on DI here.
And IMO this is great example why using DI for this this is dangerous. You're changing internal logic of models by configuring application, and you're doing it for all models and in implicit way. You don't even know which models may be affected (in some cases it may be undesired), and this is completely invisible from model perspective. It is convenient way to shoot yourself in the foot - creating custom validator (or some global config param) and using it in 20 places will take like ~15 minutes and may save you hours of debugging.
I asked "do we need factory if we require instances from |
IMO it is a good practice to allow user to use DI when he needs it and not to use DI when he does't need it. It's users' responsibility to choose if he need to use one way or another. IMHO if somebody uses DI he understands why does he use it. Another point is that this library will not be used only with AR now. It could be used in any place where you need to have some data checking logic. Middleware, object factories, anywhere. So it is not just "internal logic of models" anymore. Another use cases are coming.
No, we don't need factory if requiring instances from |
It could be great if we hear more opinions from YiiSoft team. |
@viktorprogger overall, this looks to be heading in the good direction, but without more visible use cases to see, I tend to agree with what @rob006 said. Yii 3 brings DI closer to the developer, and some will want to use it even if they are not experts and do not fully grasp the consequences of their acts. In real life, if I need to change Allowing to replace a validator through configuration may have a lot of unexpected consequences (i.e., core depend on |
IMO it is exactly opposite - people does not understand how DI works and what are the consequences of it. Even in your implementation there is fundamental flaw which ruins 2 main goals of DI - implicit dependencies and lack of global state ( Also note that if you want, nobody will forbid you to use DI for creating rules - you can still do this in |
my point of view.
should focus on the |
Should I use 2.X for new projects? |
@kids-return let's keep this conversation about the new rules implementation please. And yes, you should use 2.x for new projects, as we're all doing currently, I'd hate to see 3.x rushed just for the sake of being published. |
This is a good argument. I don't know why didn't I think about it before. I'm going to change this, but I can't give any dates, because I've changed my employer this week, and I have to join the work ASAP. |
No worries. What you did is a great starting point anyway. |
This one is now implemented. |
Hello!
So, I offer to change syntax in \yii\base\Model::rules()
For example, now we have
I offer try to code something else, for example:
I like https://github.com/Respect/Validation approach. What do you think?
UPD: I don't know why tabs and spaces are not working...
UPD2: Someone fixed it. Thank you 👍
Russian: хотелось бы писать правила, как в ссылке выше. :)
UPD: Хз почему все переносы и табы слетели... Писал в Notepad++...
UPD2: Кто-то пофиксил. Спасибо 👍
The text was updated successfully, but these errors were encountered: