检查实体关系是否存在。 (教义)

时间:2017-05-05 08:26:43

标签: php symfony doctrine-orm

我有关系:

/**
 * @ORM\OneToOne(targetEntity="Model\Entity\Image")
 * @ORM\JoinColumn(name="image_id", referencedColumnName="id")
 */
protected $image;

普通的吸气鬼:

public function getImage()
{
    return $this->image;
}

在我的枝条代码中,我称之为:

model.image.getImageURL()

但是如果数据库中没有关系,比如缺少 image_id ,那么getImage方法将返回null,而方法 getImageURL 则为Exception。我怎样才能避免它清楚。

我的解决方案是:

 protected function exist($model, $modelName) {
    if(isset($model)) {
        return $model;
    } else {
        $modelName = 'Model\Entity\\' . $modelName;
        return new $modelName();
    }
}

和getter一样:

public function getImage()
{
    return $this->exist($this->image, 'Image');
}

但我不喜欢它,对我来说似乎不是很好的解决方案。我能以Symfony方式做到这一点,我认为我错过了一些东西吗?

2 个答案:

答案 0 :(得分:1)

你真的没有遗漏任何东西。

您的实体中有可选关系,这意味着该值可以为null。 所以"对"处理这种情况的方法是在访问其上的任何方法之前检查属性是否已设置。

这意味着在一个案例中:

{% if model.image is not null %}
    {{ model.image.getimageUrl() %}
{% endif %}

并在php案例中:

if($model->getImage() !== null) {
    $url = $model->getImage()->getImageUrl();
}

其他选项将改变getImage的实现:

public function getImage() {
    return $this->image === null ? new Image() : $this->image;
}

或直接在模型实体中创建专用的getImageUrl方法:

public function getImageUrl() {
    return $this->image !== null ? $this->image->getImageUrl() : '';
}

答案 1 :(得分:0)

无法填写的唯一原因是它是否失败或无法找到关系。在这种情况下,您的解决方法也将返回null,因为它不存在。

您可以通过以下方式检查:

{% if model.image %}
  {{ model.image.imageUrl }}
{% endif %}

它会搜索get方法,因此您只需使用imageUrl即可搜索getImageUrl

使用关系时也有一点,Symfony不会做反向关系。我自己找不到问题,但是一个与之斗争的伙伴(他完全信任开发决策)告诉我你必须手动添加它,这是Symfony / Doctrine中一个已知和有意的事情。

让我举个例子OneToMany

[Entity \ Human.php]

class Human
{

  /**
   * @ORM\ManyToOne(targetEntity="Race", inversedBy="race")
   * @JoinColumn
   *
   * A human can have one race, but a race can belong to many human
   */
  private $race;

  // using optional parameter so I can demonstrate it on one way..
  // If you want it to be required, remove " = null"
  // and also remove "if ($race && ..)" 
  public function setRace(Race $race = null)
  {
    $this->race = $race; // default from bin/console doctrine:generate:entities

    // Reverse check and add if not automatically done
    if ($race && ! $race->getHumans()->contains($this)) {
      $race->addHuman($this);
    }

    return $this; // default from bin/console doctrine:generate:entities
  }
}

以及相反的网站:

[Entity \ Race.php]

class Race
{
  /**
   * @ORM\OneToMany(targetEntity="Human", mappedBy="race")
   */
  private $humans;

  public function __construct()
  {
    $this->humans = new ArrayCollection;
  }

  public function addHuman(Human $human)
  {
    $this->humans[] = $human; // default from bin/console doctrine:generate:entities

    // Custom reverse check and add
    if ($human->getRace() !== $this) {
      $human->setRace($this);
    }

    return $this; // default from bin/console doctrine:generate:entities
  }

  // also important for remove!
  public function removeHuman(Human $human)
  {
    $this->humans->removeElement($human);

    if ($human->getRace() !== null) {
      $human->setRace(null);
    }

    return $this;
  }
}