首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将有效约束与可空嵌入表单相结合

如何将有效约束与可空嵌入表单相结合
EN

Stack Overflow用户
提问于 2015-03-23 09:03:32
回答 1查看 143关注 0票数 1

如果包含在请求有效负载中,我希望将验证嵌入表单的能力与跳过此验证(如果不包括)结合起来。

我的用例如下。

我向我的控制器发送了以下json,包括资源活动和子资源文章。

代码语言:javascript
复制
{
   "campaign": {
       "name": "New campaign",
       "article": {
           "title": "How to develope faster",
           "summary": "This is a <b>summary</b>"
       }
   }
}

通过以下验证,Symfony表单将对此进行处理:

代码语言:javascript
复制
AppBundle\Document\Campaign:
  properties:
    name:
        - NotBlank:
            message: 'campaign.validation.name.not_blank'
        - Length:
            min: 1
            max: 300
            minMessage: 'campaign.validation.name.length.min'
            maxMessage: 'campaign.validation.name.length.max'
    article:
        - Valid: ~

AppBundle\Document\Article:
  properties:
    title:
        - NotBlank:
            message: 'article.validation.title.not_blank'
        - Length:
            min: 20
            max: 300
            minMessage: 'article.validation.title.length.min'
            maxMessage: 'article.validation.title.length.max'

这些表格看起来如下:

代码语言:javascript
复制
class CampaignFormType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $transformer = new FieldToModelTransformer($options['manager'], 'slug');

        $builder
            ->add('name')
            ->add('article', new ArticleFormType());

        $builder->add(
            $builder->create('brand', 'text', [
                'invalid_message' => 'campaign.validation.brand.invalid'
            ])->addModelTransformer($transformer)
        );
    }

    /**
     * {@inheritdoc}
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Document\Campaign',
            'csrf_protection'   => false
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'campaign';
    }
}

class ArticleFormType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', 'text');
    }

    /**
     * {@inheritdoc}
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Document\Article',
            'csrf_protection'   => false,
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'article';
    }
}

所以问题是,如果我在子表单中设置了有效的反差,那么验证系统总是在子资源上通过验证,即使它没有通过。因此,这个请求将失败:

代码语言:javascript
复制
{
    "campaign": {
        "name": "New campaign"
    }
}

我想提出以下几点:

  • 如果项目有效载荷有数据,那么验证它。
  • 如果项目为空或空,则不要验证子资源。

怎样才是最干净的方法呢?

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-23 10:23:32

所以我找到了正在发生的事。

我的控制器是创建表单、提交请求等的标准控制器.而且,如果文章不在json中,它不会自动被自动提交,所以在提交表单之前,它在请求中是空的。

我有3个测试数据集(场景1):

试验1:

代码语言:javascript
复制
{
    "campaign": {
        "name": "New campaign",
        "startDate": "2012-01-01",
        "endDate": "2012-02-01"
    }
}

试验2:

代码语言:javascript
复制
{
    "campaign": {
        "article": {
            "title": ""
        }
    }
}

试验3:

代码语言:javascript
复制
{
    "campaign": {
        "article": {
            "title": "",
            "summary": "Whatever valid value"
        }
    }
}

在不更改表单或验证的情况下,这就是结果:

  • 测试1:对文章的验证打开,并在article.title上抛出不为空的
  • 测试2:对文章的验证打开,并在article.title上抛出不为空
  • 测试3:对文章的验证打开,并在article.title上抛出不为空

键是修改表单字段项目,并在其中添加必需的选项false:

代码语言:javascript
复制
public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $transformer = new FieldToModelTransformer($options['manager'], 'slug');

        $builder
            ->add('name', 'text')
            ->add('article', new ArticleFormType(), [
                'required' => false
            ]);

        $builder->add(
            $builder->create('brand', 'text', [
                'invalid_message' => 'campaign.validation.brand.invalid'
            ])->addModelTransformer($transformer)
        );
    }

通过这种方式执行相同的树测试,结果如下(场景2):

  • 测试1:对文章的验证没有打开
  • 测试2:对项目的验证甚至不会将标题传递为空或空。
  • 测试3:对文章的验证打开,并在article.title上抛出不为空

因此,总结而言,我需要将嵌入表单上的必需的false设置为可选的,但是如果我传递属性等于空或空的嵌入对象,则会自动清除。

我期望场景2的Test 2打开标题上的验证,但这并不是因为对空属性的清理。

我是说,我预料到这个结果:

  • 测试1:对文章的验证没有打开
  • 测试2:对文章的验证打开并在article.title上抛出不空白
  • 测试3:对文章的验证打开,并在article.title上抛出不为空

这种行为是有意义的,但我没想到它是默认的,所以也许有效约束的文档可能更明确,或者我对这个假设是错误的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29206399

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档