【问题标题】:Symfony2: Using Ajax and Forms to create related entities without loading all entitiesSymfony2:使用 Ajax 和 Forms 创建相关实体而不加载所有实体
【发布时间】:2017-05-03 10:34:25
【问题描述】:

我们有一个 Symfony2 应用程序,它允许管理员使用 Ajax POST 请求将付款记入用户帐户。 POST 请求发送由 Symfony 控制器处理的 JSON。控制器应该创建一个“支付”实体,对其进行验证并持久化。我们希望利用 Symfony 表单系统的内置验证。

例如,id 为 20 的用户使用 100p 的信用,POST 的 JSON 应该看起来像 ...

{"user":"20","amount":"100","description":"test payment","paymentType":"credit"}

在 Symfony 端,我们有一个 PaymentType 表单;

class PaymentType extends AbstractType

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('user', 'entity', [
        'class' => 'OurAppBundle\Entity\User',
        'choice_label' => 'email',
        'multiple'     => false,
        'expanded'     => true,
    ]);
    $builder->add('paymentType', 'choice', [
        'choices' => [ 1 => 'credit', 2 => 'debit'],
        'choices_as_values' => true,

    ]);
    $builder->add('amount', 'number');
    $builder->add('description', 'textarea');
}

支付实体与用户实体相关,并包含验证;

class Payment
{
const TYPE_CREDIT = 'credit';
const TYPE_DEBIT = 'debit';

use TimestampableTrait;

/**
 * The ID of the payment
 *
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;


/**
 * the User object
 *
 * @var User
 *
 * @ORM\ManyToOne(targetEntity="User", inversedBy="payments")
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)
 */
protected $user;

/**
 * payment type
 *
 * either 'credit' - a credit to the user's account
 * or 'debit' - money taken out their account
 *
 * @var string
 *
 * @ORM\Column(name="payment_type", type="string", length=7, nullable=false)
 *
 * @Assert\Choice(choices= {"credit", "debit"}, message="Choose a valid payment type")
 */
protected $paymentType;

/**
 * amount
 *
 * amount of payment, in pence
 *
 * @var int
 *
 * @ORM\Column(name="amount", type="integer", nullable=false)
 *
 * @Assert\Range(
 *      min = 1,
 *      max = 2000,
 *      minMessage = "Payments must be positive",
 *      maxMessage = "You cannot credit/debit more than £20"
 * )
 */
protected $amount;

/**
 * a string describing the transaction
 *
 * @var string
 *
 * @ORM\Column(name="description", type="string", length=255, nullable=false)
 *
 * @Assert\NotBlank(message="Please enter a description")
 */
protected $description;
....

我们在控制器中有如下代码:

public function creditUserAction(Request $request)
{
      $body = $request->getContent();
      $formData = json_decode($body, true);

      $payment = new Payment();
      $form = $this->createForm(new PaymentType(), $payment);
      $form->submit($data);
      if ($form->isValid()) {
          // persist and flush .....

      } ....

问题是,当通过createForm加载PaymentType表单时,Doctrine试图从数据库中加载所有Users,用户数有几万。

所以,我的问题是 - 有没有更好的方法来创建一个实体,使用 Ajax POST 请求,它与使用 Symfony Forms 的另一个实体相关,其中相关实体有数千个实例?

【问题讨论】:

    标签: symfony doctrine-orm


    【解决方案1】:

    您无需创建表单即可验证您的实体

    $validator = $this->get('validator');
    $errors = $validator->validate($payment);
    if(count($errors)) {
        //...
    }
    

    【讨论】:

    • 同意。我希望使用 Symfony 表单也不必手动设置实体的每个属性 - 但是,手动设置每个属性并不是一项繁重的任务。感谢您的帮助,我会使用您建议的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多