У меня не может быть более 2 сопоставлений vichuploader | Симфония 3.4

я в полном отчаянии!! Прошу вашей помощи! вот уже почти две недели блокирую по этому пункту и не сплю почти ночами :-(

контекст:

Symfony 3.4 вич-аплодер "^1.4"

Я получаю это исключение:

SQLSTATE [23000]: нарушение ограничения целостности: 1048 Столбец «document_name» не может быть нулевым

Я объясняю свою проблему:

- У меня есть связь OneToOne между двумя объектами (NoteFrais и Justificatif).
- У каждого NoteFrais есть один Justificatif.
- Justificatif — это файл, который может быть загружен с помощью vichUplodable.
- Все отлично работает в моей локальной среде.
- Проблема возникает только на моей версии в продакшене на сервере. В этом же проекте у меня уже есть другое сопоставление vich_uploader для других отношений между другими сущностями. У них все работает идеально.

Вот моя конфигурация:

parameters:
locale: fr
app.path.logos: /uploads/logos
app.path.imports: /uploads/imports
app.path.documents: /uploads/documents

vich_uploader:
db_driver: orm
mappings:
    logo:
        uri_prefix: '%app.path.logos%'
        upload_destination: '%kernel.root_dir%/../web%app.path.logos%'
        namer: vich_uploader.namer_uniqid
        inject_on_load:     false
        delete_on_update:   true
        delete_on_remove:   true
    import:
        uri_prefix: '%app.path.imports%'
        upload_destination: '%kernel.root_dir%/../web%app.path.imports%'
        namer: vich_uploader.namer_uniqid
        inject_on_load:     false
        delete_on_update:   true
        delete_on_remove:   true
    document:
        uri_prefix: '%app.path.documents%'
        upload_destination: '%kernel.root_dir%/../web%app.path.documents%'
        namer: vich_uploader.namer_uniqid
        inject_on_load:     false
        delete_on_update:   true
        delete_on_remove:   true

У меня нет проблем с первыми двумя сопоставлениями (логотип и импорт) как в локальной среде, так и на рабочем сервере.

Вот объект Justificatif(@vich/uploadable)

**
* Justificatif
*
* @ORM\Table(name="justificatif")
* @ORM\Entity(repositoryClass="MKG\MystiBundle\Repository\JustificatifRepository")
* @vich\Uploadable
 */
class Justificatif
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * NOTE: This is not a mapped field of entity metadata, just a simple property.
 *
 * @Vich\UploadableField(mapping="document", fileNameProperty="documentName")
 *
 * @var File
 */
private $justificatifFile;

/**
 * @ORM\Column(type="string", length=255)
 *
 * @var string
 */
private $documentName;


/**
 * @ORM\Column(type="datetime")
 *
 * @var \DateTime
 */
private $updatedAt;

/**
 * Constructor
 */
public function __construct()
{
    $this->updatedAt = new \DateTime();
}

/**
 * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
 * of 'UploadedFile' is injected into this setter to trigger the  update. If this
 * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
 * must be able to accept an instance of 'File' as the bundle will inject one here
 * during Doctrine hydration.
 *
 * @param File|UploadedFile $justificatif
 */
public function setJustificatifFile(File $justificatif = null)
{
    $this->justificatifFile = $justificatif;

    if ($justificatif) {
        $this->updatedAt =  new \DateTime('now');
    }
}

/**
 * @return File|null
 */
public function getJustificatifFile()
{
    return $this->justificatifFile;
}



/**
 *
 * @param $documentName
 *
 * @return $this
 */
public function setDocumentName($documentName)
{
    $this->documentName = $documentName;

    return $this;
}

/**
 * @return string|null
 */
public function getDocumentName()
{
    return $this->documentName;
}

/**
 * Set updatedAt
 *
 * @param \DateTime $updatedAt
 *
 * @return Justificatif
 */
public function setUpdatedAt($updatedAt)
{
    $this->updatedAt = $updatedAt;

    return $this;
}

/**
 * Get updatedAt
 *
 * @return \DateTime
 */
public function getUpdatedAt()
{
    return $this->updatedAt;
}

/**
 * Get id
 *
 * @return int
 */
public function getId()
{
    return $this->id;
}
}

Вот сущность NoteFrais (с отношением):

/**
 * NoteFrais
 *
 * @ORM\Table(name="note_frais")
 * @ORM\Entity(repositoryClass="MKG\MystiBundle\Repository\NoteFraisRepository")
 * @Vich\Uploadable
 */
 class NoteFrais
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\ManyToOne(targetEntity="MKG\MystiBundle\Entity\Mission", cascade={"persist"})
 * @ORM\JoinColumn(name="mission_id", referencedColumnName="id", onDelete="CASCADE", nullable=true)
 */
private $mission;

/**
 * @ORM\ManyToOne(targetEntity="MKG\MystiBundle\Entity\CodeComptable", cascade={"persist"})
 * @ORM\JoinColumn(name="compte_comptable_id", referencedColumnName="id", onDelete="SET NULL", nullable=true)
 */
private $compteComptable;

/**
 * @var string
 *
 * @ORM\Column(name="montant_defraiement_max", type="string", length=255, nullable=false)
 */
private $montantDefraiementMax;

/**
 * @var string
 *
 * @ORM\Column(name="refacturation_client", type="string", length=255, nullable=true)
 */
private $refacturationClient;

/**
 * @var string
 *
 * @ORM\Column(name="total_defraiement", type="string", length=255, nullable=true)
 */
private $totalDefraiement;

/**
 * @var string
 *
 * @ORM\Column(name="total_refacturation", type="string", length=255, nullable=true)
 */
private $totalRefacturation;

/**
 * @var string
 *
 * @ORM\Column(name="compte_avances_et_acomptes", type="string", length=255, nullable=true)
 */
private $compteAvancesEtAcomptes;

/**
 * @var string
 *
 * @ORM\Column(name="admin_current_user", type="string", length=255, nullable=true)
 */
private $currentUser;

/**
 * @var string
 *
 * @ORM\Column(name="code_affaire", type="string", length=255, nullable=true)
 */
private $codeAffaire;

/**
 * @var string
 *
 * @ORM\Column(name="etat", type="string", length=255, nullable=true)
 */
private $etat;

/**
 * @ORM\OneToOne(targetEntity="Justificatif", cascade={"persist"})
 * @ORM\JoinColumn(name="justificatif_id", referencedColumnName="id", onDelete="CASCADE", nullable=true)
 */
private $justificatif;

/**
 * @var \DateTime
 *
 * @ORM\Column(name="dateCreation", type="datetime")
 */
private $dateCreation;


public function __construct() {

    $this->dateCreation = new \DateTime;
    $this->etat = "0";
}



/**
 * Get id
 *
 * @return integer
 */
public function getId()
{
    return $this->id;
}

//======== Getters et Setters ========//

/**
 * Set justificatif
 *
 * @param \MKG\MystiBundle\Entity\Justificatif $justificatif
 *
 * @return NoteFrais
 */
public function setJustificatif(\MKG\MystiBundle\Entity\Justificatif $justificatif = null)
{
    $this->justificatif = $justificatif;

    return $this;
}

/**
 * @return \MKG\MystiBundle\Entity\Justificatif
 */
public function getJustificatif()
{
    return $this->justificatif;
}

//======== Getters et Setters ========//

}

Оправдательная форма:

public function buildForm(FormBuilderInterface $builder, array $options)
   {
       $builder->add('justificatifFile', FileType::class, array(
       //'data_class' => null,
       'label' => false,
       'required' => true,
       'attr' => array(
           'class' => 'NoteFraisBootstrapFileInput',
           'type' => 'file',
           'placeholder' => 'Selectionner un justificatif (jpeg, png, jpg, pdf)',
           'data-preview-file-type' => 'text',
           'data-allowed-file-extensions' => '["jpeg", "png", "jpg", "pdf"]',
       )
   ));
   }

Я использую FileType вместо VichType, обычно он отлично работает, так что проблема не оттуда ...

Вот форма NoteFrais:

public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
    //->add('circuit')
  //======Autres champs======//

    ->add('justificatif', JustificatifType::class, array(
        'required' => false));
}

Много чего перепробовал, пересмотрел свой код, читал страницы и страницы форума...

Для информации:

-У меня есть права на папки назначения на сервере.
-Я несколько раз пытался изменить имя проблемного сопоставления...
- Я так чистил кеш (приобретал, заказывал.. .)

С другой стороны:

Я заметил, что я указываю свою сущность Justificatif на другое существующее сопоставление, все работает отлично ??? Круто... Но это не то, чего я хочу... Я хочу сохранить 3 разных совпадения и хочу понять, почему это 3-е сопоставление игнорируется.

Спасибо тем, кто уделил мне время. :-)


person Moh    schedule 03.01.2019    source источник


Ответы (2)


В отношениях вы должны добавить другую форму как EntityType в свой построитель форм. Если OneToOne как EntityType и OneToMany как CollectionType.

->add('justificatif', EntityType::class, array(
    'class' => 'YourBundle:Justificatif',
    'required' => false
));

вы также можете добавить nullable true к вашему атрибуту $documentName в Justificatif Entity, чтобы избежать проблем с вставленными пустыми значениями.

 * @ORM\Column(type="string", length=255, nullable=true)
 *
 * @var string
 */
private $documentName;

ОТРЕДАКТИРОВАНО Действительно, поле не сохраняется, оно должно быть аннотировано как Файл в объекте атрибута. Вы можете использовать Vich\UploaderBundle\Entity\File embeddable для хранения информации о файле в вашем объекте ORM.

В вашем классе Justificatif

/**
     * NOTE: This is not a mapped field of entity metadata, just a simple property.
     * 
     * @Vich\UploadableField(mapping="document", fileNameProperty="document.name")
     * 
     * @var File
     */
    private $justificatifFile;

    /**
     * @ORM\Embedded(class="Vich\UploaderBundle\Entity\File")
     *
     * @var EmbeddedFile
     */
    private $fileJustificatif;

 /**
     * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
     * of 'UploadedFile' is injected into this setter to trigger the  update. If this
     * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
     * must be able to accept an instance of 'File' as the bundle will inject one here
     * during Doctrine hydration.
     *
     * @param File|UploadedFile $justificatifFile
     */
    public function setjustificatifFile(?File $justificatifFile = null)
    {
        $this->justificatifFile = $justificatifFile;

        if (null !== $justificatifFile) {
            // It is required that at least one field changes if you are using doctrine
            // otherwise the event listeners won't be called and the file is lost
            $this->updatedAt = new \DateTimeImmutable();
        }
    }

    public function getjustificatifFile(): ?File
    {
        return $this->justificatifFile;
    }

Из документации https://github.com/dustin10/VichUploaderBundle/blob/master/Resources/doc/usage.md

person hoover_D    schedule 04.01.2019
comment
Спасибо за ваш ответ. Я уже пытался установить nullable=true. Действительно, это работа, и я не получаю исключения. Но файл не загружается...?? У меня такое впечатление, что vichuploaderBundle полностью игнорирует мою последнюю конфигурацию. @Vich\UploadableField(отображение=документ, имя_файлаProperty=имя_документа) - person Moh; 04.01.2019
comment
действительно, настойчивость нужно было заставить. Можете ли вы проверить мой отредактированный ответ, чтобы увидеть, работает ли он? - person hoover_D; 04.01.2019
comment
Я добавил его в свою сущность Justificatif, но не могу сгенерировать геттеры и сеттеры для этого нового атрибута, потому что @var EmbeddedFile и @ORM\Embedded(class=Vich\UploaderBundle\Entity\File) не найдены...?? я никогда не видел? - person Moh; 04.01.2019
comment
Вы добавили использование для Vich\UploaderBundle\Entity\File ? - person hoover_D; 04.01.2019
comment
Проверьте документы в моем отредактированном посте, есть геттеры и сеттеры - person hoover_D; 04.01.2019
comment
хорошо, спасибо, но это пространство имен Vich\UploaderBundle\Entity\File не существует? - person Moh; 04.01.2019

Наконец-то я решил эту проблему! На самом деле это было очень глупо... Проблема касается только среды prod, а значит используемая конфигурация должна быть прописана из файла config_prod.yml и это был не мой случай! Большую часть времени я нахожусь в среде разработки, поэтому я перестал игнорировать существование этого файла... Спасибо всем, кто пытался мне помочь!

person Moh    schedule 08.01.2019