dongxueji2838
2014-04-11 07:08
浏览 46
已采纳

从数据数组中填充实体而不使用表单/请求

Just wondering if it is possible to only use some parts of the symfony form handling. For exampe, when creating CRUD actions via generate:doctrine:crud I get something in my Controller (for handling create User POST requests) that looks like this:

$entity = new User();
$form = $this->createForm(new UserType(), $entity,
        array(
        'action' => $this->generateUrl('user_create'),
        'method' => 'POST',
));
$form->handleRequest($request);
//Here I have a filled Entity

But what I want is to have this in a more reusable solution. Currently I have my business logic in a service called UserModel. Here I also want to have the create method to create, validate and persist a new entity. Tough the UserModel should also be callable from some Command scripts via the console, so I probably won't always have Request nor a Form.

So now from the above code I know that Symfony is already somehow populating data to an Entity according to the UserType definition, but how could I do that manually without having a Form or a Request and instead just some array of data?
So that I don't have to take care of setting the properties myself.

Edit: The validation is no issue for populating the entity, I'm using the validator later on the populated entity before persisting the data.
And also important for me would be that the passed related entity ids will be handled/loaded automatically.

图片转代码服务由CSDN问答提供 功能建议

只是想知道是否可以只使用symfony表单处理的某些部分。 例如,当通过 generate:doctrine:crud 创建CRUD操作时,我在Controller中获得了一些内容(用于处理创建用户POST请求),如下所示:

   $ entity = new User(); 
 $ form = $ this-> createForm(new UserType(),$ entity,
 array(
'action'=> $ this-> generateUrl(  'user_create'),
'方法'=>'POST',
)); 
 $ form-> handleRequest($ request); 
 //这里我有一个填充的实体
   
 
 

但我想要的是将其置于更可重用的解决方案中。 目前,我在一个名为 UserModel 的服务中拥有我的业务逻辑。 在这里,我还希望使用 create 方法来创建,验证和持久化新实体。 强大的 UserModel 也应该可以通过控制台从某些Command脚本中调用,所以我可能不会总是有 Request Form

所以现在从上面的代码中我知道Symfony已经以某种方式根据 UserType 定义将数据填充到实体,但是我怎么能在没有 有 Form Request 而只是一些数据?
所以我不需要自己设置属性。

编辑: 验证对于填充实体没有问题,我稍后在填充的实体上使用验证器,然后再保留 数据。
对我来说同样重要的是传递的相关实体ID 将自动处理/加载。

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • dougan1205 2014-04-11 09:07
    已采纳

    you may still use the Form component, but instead of using handleRequest, you should use directly submit.

    If you are curious, you should look up the code on github for both handleRequest and what it actually does ; you'll see that it just do some verification, takes the data from the Request, and then uses the submit method of the Form.

    So, basically, you can use only the submit method with the data you wish to use. It even validates your entity. :)

    UPDATE

    And for the concern of creating / updating related entities, if your relation have a persist / update cascade, it should roll out from itself without you doing a single thing, except persist + flush on your main entity.

    打赏 评论
  • duan6301 2014-04-11 07:27

    If you do not worry about handling validation like things, you can do something like I have done.

    You can define a trait or include the fromArray function in your entity classes.

    trait EntityHydrationMethod
    {
        public function fromArray($data = array())
        {
            foreach ($data as $property => $value) {
                $method = "set{$property}";
                $this->$method($value);
            }
        }
    }
    

    If you defined trait, you can use it in your entities like:

    class User{
    
      use EntityHydrationMethod;
    
    }
    

    Then from your user model you can define your create function something like:

    public function create($data = array())
    {
        $entity = new User();
        $entity->fromArray($data);
        return $entity;
    }
    

    -Updated-

    As you updated your question. you may achieve this by defining a trait or include the createFromArray function in your EntityRepository classes.

    trait RepositoryCreateMethod {
        public function createFromArray($data)
        {
            $class = $this->getClassName();
    
            $object = new $class();
    
            $meta = $this->getClassMetadata();
    
            foreach ($data as $property => $value) {
                $v = $value;
    
                if(!empty($value) && $meta->hasAssociation($property)) {
                    $map = $meta->getAssociationMapping($property);
                    $v = $this->_em->getRepository($map['targetEntity'])->find($value);
                    if(empty($v)){
                        throw new \Exception('Associate data not found');
                    }
                }
    
                $method = "set{$property}";
                $object->$method($v);
            }
    
            return $object;
        }
    }
    

    If you defined trait, you can use it in your Repository like:

    class UserRepository{
    
      use RepositoryCreateMethod;
    
    }
    

    Then you can use this something like call from controller:

    $user = $this->getDoctrine()
                 ->getRepository('YourBundle:User')
                 ->createFromArray($data);
    
    打赏 评论

相关推荐 更多相似问题