Ciao a tutti, scusate ma sto cercando di fare una cosa "apparentemente" banalissima ma non riesco a venirne a capo.
Ho una tabella nel db con 2 classici campi dove memorizzo data ed ora di creazione del record. Per questo si chiamano "data_cre" e "ora_cre".
Vorrei che il mio Model automaticamente settasse questi campi con la data e l’ora corrente al momento dell’action Save()
La prima cosa che mi era venuta in mente era di mettere nel model una cosa simile:
public function beforeSave() {
$this->date_cre = date("Y-m-d");
$this->ora_cre = date("H:i:s");
return parent::beforeSave();
}
ma poi mannaggia a me, leggendo qua e là sono incappato in questa guida dove addirittura invita a mettere un behavior, ma pur provando non ci son riuscito.
Potete consigliarmi qual’è il modo migliore meno incasinato?
Si esatto, c’è un behavior che fa esattamente questo, imposta una data quando crei o modifichi un modello.
Al behavior devi dire quale campo usare per la data creazione e quale per la data aggiornamento poi fa tutto lui, io lo uso in quasi tutti i modelli.
Questa classe però lavora con i timestamp quindi avrai data e ora tutti in un unico campo sotto forma di timestamp appunto…
Il funzionamento e l’uso del behavior è molto semplice, nel tuo modello dichiari una cosa simile a questa:
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created',
'updatedAtAttribute' => 'updated',
'value' => new Expression('NOW()'),
],
];
}
Anche se tu volessi farlo con un tuo metodo ti consiglio di scrivere un semplice behavior, magari prendendo spunto da quello esistente così non dovrai mettere beforeSave sparpagliati per i tuoi modelli!
edit: quella guida non funziona perché obsoleta, segui le info su questo link
Ciao, leggendo la guida di TimestampBehavior dice:
$updatedAtAttribute public property
string $updatedAtAttribute = 'updated_at'
The attribute that will receive timestamp value. Set this property to false if you do not want to record the update time.
Io ho una tabella dove non esiste il campo updated_at per cui dovrei settare a falso questa proprietà.
Solo che ho provato così:
public function behaviors()
{
return [
TimestampBehavior::className(),
'updatedAtAttribute' => FALSE,
];
}
Per "soprassedere" questo errore, ho creato nella tabella anche il campo "updated_at"
La cosa che mi "puzza" è che mi dà questo errore "Class created_at does not exist"
Questo il codice del mio model:
namespace app\models\admin;
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\db\Expression;
...
public function behaviors()
{
return [
TimestampBehavior::className(),
'createdAtAttribute' => 'created_at',
'updatedAtAttribute' => 'updated_at',
'value' => new Expression('NOW()'),
];
}
Penso che il problema (e forse anche il discorso FALSE) sia perchè cmq questa procedura ha qualcosa che non va.
Sono sicuro che nella tabella del db questi due campi esistono e sono di tipo TIMESTAMP
Alla fine ho risolto tutto, anche se a dire il vero non so spiegarmi il perchè…
Ad ogni modo, a futura memoria, potesse interessare a qualcun’altro ecco la giusta sintassi che “nel mio caso” funziona correttamente
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\db\Expression;
...
public function behaviors()
{
return [
'timestamp' => [
'class' => TimestampBehavior::className(),
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => ['created_at'],
ActiveRecord::EVENT_BEFORE_UPDATE => false,//'updated_at',
],
'value' => new Expression('NOW()'),
],
];
}
Ripeto non so quale sia il motivo.
Forse (e dico forse) può centrare il fatto che ho creato tutti i models che riguardano tabelle di amministrazione (come questa su cui ho fatto la prova) in una sottodirectory chiamata "admin"
Ho infatti dovuto aggiungere all’inizio del model la riga
use yii\db\ActiveRecord;
senza la quale andava di default a cercarmi la classe ActiveRecord nella subdirectory admin. Quindi forse bastava fare lo stesso nella soluzione apparentemente simile scritta nei post precedenti e nella guida ufficiale del TimestampBehavior.
Stesso dicasi per il discorso di FALSE che ora me l’ha preso tranquillamente. Forse prima non trovando la classe non accettava il valore. Il problema era che in questo modo mi ha detto “palesemente” l’errore, mentre prima mi “deviava” con altri errori collaterali.