limoncello-php / app

Quick start JSON API application
MIT License
83 stars 7 forks source link

New Validation Ruleset on update #25

Closed dreamsbond closed 7 years ago

dreamsbond commented 7 years ago

Having looked into the new validation ruleset implementation of 0.7.x, i found that there was a problem differentiate the unique of record.

i used to implement like this in previous version:

protected function name($index = null): RuleInterface
{
    $primaryKey = $index === null ? $index : [Model::FIELD_ID, $index];

    $maxLength = Model::getAttributeLengths()[Model::FIELD_NAME];
    $name = $this->andX(
        $this->stringLength(Model::MIN_NAME_LENGTH, $maxLength),
        $this->isString()
    );

    return $this->andX($name, $this->isUnique(Model::TABLE_NAME, Model::FIELD_NAME, false, $primaryKey));
}

the RULE_INDEX was no longer presented, i can't use it anymore.

dreamsbond commented 7 years ago

@neomerx i think i found the solution, the UniqueInDbTableSingleWithDoctrine in ExistInDatabaseTrait ...

neomerx commented 7 years ago

From 0.6.x to 0.7.x the validation component was changed most. Now it's more fixable and faster.

Now back to your question. As far as I understand you wish to check input data on create/update and make sure that one of the input attributes is

neomerx commented 7 years ago

@dreamsbond As an example I've modified rule \App\Json\Validators\Rules\UserRules::firstName


    /**
     * @return RuleInterface
     */
    public static function firstName(): RuleInterface
    {
        return self::isString(
            self::andX(
                self::stringLengthMax(Model::getAttributeLengths()[Model::FIELD_FIRST_NAME]),
                self::unique(Model::TABLE_NAME, Model::FIELD_FIRST_NAME)
            )
        );
    }
dreamsbond commented 7 years ago

@neomerx ya, the new ruleset was very useful for better isolation and separation on validation.

what i would like to do is bypass the uniqueness checking on update for the use case of having the same entry (e.g. name) during update causing validation errors in most case

neomerx commented 7 years ago

2 rules? uniqueName and name?

neomerx commented 7 years ago

What I'm proud about the new validation is that it's cacheable and while validation it also transforms (e.g. string to DateTime) and captures the data. So it's fast and efficient.

dreamsbond commented 7 years ago

@neomerx ya. i think so. i was not aware of doing in 2 rules way like uniqueName and name.

dreamsbond commented 7 years ago

another question about the validation message, i used to make custom message by this way: by override the constructor:

public function __construct(ContainerInterface $container, $jsonType, $rules, $errorStatus = JsonApiResponse::HTTP_UNPROCESSABLE_ENTITY)
{
    parent::__construct($container, $jsonType, $rules, $errorStatus);

    $container[TranslatorInterface::class] = function () {
        return new Translator(Validation::getLocaleCode(), Validation::getMessages());
    };
}

is it no longer required and obsolete?

neomerx commented 7 years ago

The idea of having separate rules is reusability. Typically rules are very similar for create and update. Though in create they are usually required but in update not.

neomerx commented 7 years ago

L10n is a new feature as well. Now you can have messages in many locales.

If you want to have custom errors you typically add new error code and corresponding message.

neomerx commented 7 years ago

If you want to get those messages you can get \Limoncello\Contracts\L10n\FormatterFactoryInterface from container. It has methods for getting messages in specific or default locale. Currently, validation uses default locale but it shuldn't be difficult to add locale propery to current user and use it.