我已經創建了一個Object to ID Data Transformer。它是自定義ObjectIdType的一部分,它允許我輸入文檔的ID而不是使用「文檔」表單類型。這對於MongoDB非常有用(可能有1億個文檔可供選擇)。Symfony2 - 由於設置器上的類型提示而被迫在DataTransformer內部進行驗證
數據轉換器對該ID執行查詢並返回一個對象。如果找不到對象,則返回null。問題是 - 有時候null是一個可接受的值,有時它不是。
即使我添加NOTNULL驗證,我碰到下面的錯誤 -
捕致命錯誤:傳遞給角色:: setPlayer(參數1)必須是文件\ Player實例中,空給出
因此,無論驗證失敗,它都會調用setter。我通過在變換器中拋出一個TransformationFailedException來解決這個問題 - 但這似乎是一個糟糕的主意。我不應該使用數據轉換器來驗證。
變壓器的代碼如下。我想要的是能夠將驗證器放在正確的位置,並攔截setter,使其不會被調用。一般來說,這似乎有點代碼味,我很想知道其他人是如何解決這個問題的。
class ObjectToIdTransformer implements DataTransformerInterface
{
private $objectLocator;
private $objectName;
private $optional;
/**
* @param ObjectLocator $objectLocator
* @param $objectName
*/
public function __construct(ObjectLocator $objectLocator, $objectName, $optional = false)
{
$this->objectLocator = $objectLocator;
$this->objectName = $objectName;
$this->optional = $optional;
}
/**
* {@inheritdoc}
*/
public function transform($value)
{
if (null === $value) {
return null;
}
if (!$value instanceof BaseObject) {
throw new TransformationFailedException("transform() expects an instance of BaseObject.");
}
return $value->getId();
}
/**
* {@inheritdoc}
*/
public function reverseTransform($value)
{
if (null === $value) {
return null;
}
$repo = $this->objectLocator->getRepository($this->objectName);
$object = $repo->find($value);
if (!$this->optional && !$object) {
throw new TransformationFailedException("This is probably a bad place to validate data.");
}
return $object;
}
}
哦,我沒根本不需要setter中的null值,因爲null不是有效的選項,所以它被有意刪除。你認爲我應該允許null,然後讓驗證器處理它嗎?我沒有考慮過這個問題,因爲我的獲得者和制定者都嚴格地設置,以反映底層資產是否可以爲空。 – james853
是的,你應該允許'null'值並讓驗證器處理它。 –
好的,謝謝。老實說,我認爲這是一種解決方法,但我認爲沒有更好的方法。如果在通過setter將對象提交給對象之前,有人會攔截提交的值,但我認爲這只是Symfony的限制。 – james853