Doctrine – vychozi hodnota CURRENT_TIMESTAMP

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
radik
Člen | 21
+
0
-

Cau,
jak mam udelat, kdyz mam v entite udelany tohle:

/**
     * @ORM\Column(type="datetime", options={"default"="CURRENT_TIMESTAMP"})
     */
    protected $created_at;

v databazi to je vytvoreno spravne (takze kdyz v tomto sloupci necham NULL, tak to doplni aktualni cas), ale pres dcotrine me to hodi chybu, ze tam dava NULL, kdyz je to povinne.

Je nejaka finta jak to udelat a nebo nastavit, ze sloupec muze byt i NULL a spolehnout se, ze DB vzdy doplni a nevznikne zadna moznost kdy by se nedoplnilo?

Dik

Svaťa Šimara
Člen | 98
+
+4
-

Jasně, vykašli se na logiku v databázi a udržuj si ji v kódu:

	/**
	 * @ORM\Column(type="datetime")
	 */
protected $createdAt;

	public function __construct() {
		$this->createdAt = new DateTime();
	}
Oli
Člen | 1215
+
0
-

Jde to takhle:

/**
 * @var DateTime
 * @ORM\Column(name="date_updated", type="datetime", nullable=false,
 *   options={"default": "CURRENT_TIMESTAMP"}
 * )
 */
 private $dateUpdated = 'CURRENT_TIMESTAMP';

Edit: Řešení od @Fafin je rozhodně lepší. Moje řešení se hodí jen pokud je potřeba zachovat stávající databázi a promítnout ji do modelu.

Editoval Oli (22. 12. 2016 7:47)

Svaťa Šimara
Člen | 98
+
0
-

Oli napsal(a):

Jde to takhle:

/**
 * @var DateTime
 * @ORM\Column(name="date_updated", type="datetime", nullable=false,
 *   options={"default": "CURRENT_TIMESTAMP"}
 * )
 */
 private $dateUpdated = 'CURRENT_TIMESTAMP';

Anotace @var DateTime není pravda, když při vytvoření objektu tam bude string, ne?

Oli
Člen | 1215
+
0
-

Vrací to datetime. Protože CURRENT_TIMESTAMP je „klíčové slovo“, které uloží do databáze aktuální čas. A ten sloupec je typu datetime, který Doctrine mapuje na \DateTime.

Koneckonců, tohle přesně ti vygeneruje Doctrine, pokud reverzně vygeneruješ entity z databáze a databáze má default value CURRENT_TIMESTAMP.

Svaťa Šimara
Člen | 98
+
0
-

@Oli Vskutku? Co udělá následující kód?

class Article {

/**
 * @var DateTime
 * @ORM\Column(name="date_updated", type="datetime", nullable=false,
 *   options={"default": "CURRENT_TIMESTAMP"}
 * )
 */
 private $dateUpdated = 'CURRENT_TIMESTAMP';

 /**
  * @return string
  */
 public function getLastUpdate() {
	return $this->dateUpdated->format('Y-m-d');
 }

}

$article = new Article();
echo $article->getLastUpdate();

Je anotace opravdu pravdivá?

Oli
Člen | 1215
+
0
-

Jasně, máš pravdu. Pokud se ještě nevykoná dotaz od databáze, tak tam bude string. Je to stejná situace jako tady je null.

Tvoje řešení je jednoznačně správnější/lepší. A ještě před měsícem bych napsal to samé. Dostal jsem se ale k přepisování aplikace, kde se reverzně vytvořili entity z databáze a k té databázi přistupuje víc aplikací. A všechny počítají s tím, že tam to „CURRENT_TIMESTAMP“ je. A protože na to spoléhají uplně „všude“, tak je důležitý tam tu funkcionalitu nechat. Chtěl jsem proto ukázat alternativu k tvému řešení, které by „CURRENT_TIMESTAMP“ zahodilo…

Svaťa Šimara
Člen | 98
+
0
-

@Oli Tvoje situace z originální ukázky nebyla vůbec zřejmá. Ty jsi v situaci – model = databáze, a musíš přizpůsobovat PHP databázi.

Moje reakce je „neudržuj logiku v DB, pokud můžeš v PHP“, což je podle mě při použití Doctrine best practice – databáze je prostě úložiště.

A pokud budu chtít zachovat kompatibilitu s CURRENT_TIMESTAMP, tak upravím migraci pro danou databázi a nemusím hackovat entitu případně mapování.

Oli
Člen | 1215
+
0
-

@Fafin máš pravdu, nenapsal jsem to nejštťastněji. Omlouvám se. Připojil jsem, poznámku k původnímu postu, aby to bylo zřejmé.