$Model->Attributes=$_Post['newsletter'] Ignora I Valori Non Db

Ho un model ‘Newsletter’ che oltre ai campi di db contiene una proprietà pubblica ‘rcpt_address_list’, che è poi solo una stringa

Ho verificato che sull’azione post il campo viene spedito come Newsletter[“rcpt_address_list”], nella stessa nomenclatura POST degli altri.

Quando però effetto




$model->attributes=$_POST['Newsletter'];



questo attributo NON viene impostato.

Ho già verificato che nella vista della form il nome del campo è corretto, così come ho verificato che sia in ‘safe’ (e comunque non ho alcun problema segnalato nei log) …

Idee?

Può essere che il formato di questo campo non sia valido? Puoi mostrarci il model?

L’ho dichiarato così nella classe Newsletter




public $rcpt_address_list;  // stringa separata da virgola con gli indirizzi email



e come rules ho




array('rcpt_address_list', 'safe' ),



Ho verificato che inviando un qualsiasi testo questo provoca il popolamento corretto del relativo parametro $_POST

– tutto qui –

Aggiungo questo snippet




public function actionSend($id)

	{

		$model=$this->loadModel($id);


		$client = Yii::app()->user->getClient();


		if(isset($_POST['Newsletter']))

		{	

			Yii::trace( "actionSend POST" . print_r($_POST["Newsletter"], true), "mirko" );

			$model->attributes = $_POST['Newsletter'];

			

			$model->client_id = $client->id;

			if($model->save()) {


				$model->rcpt_address_list = $_POST['Newsletter']["rcpt_address_list"];


				Yii::trace( "actionSend newsletter attrs" . print_r($model->attributes, true), "mirko" );



Si noti che nel primo “trace” ci sono i POST e qui il valore di rcpt_address_list compare, dopo il save però non c’è più, e non serve a nulla neppure assegnarlo a forza ! Non capisco… e sono certo che sarà una sciocchezza …

Aggiungo un altra cosa assurda.

Se dopo il model->save() invece di fare il redirect a view faccio un render di ‘update’, ottengo che TUTTI i campi sono popolati … quindi … nel model c’è anche questo attributo, ma ancora una volta, facendo il print_r di $model->attributes NON compare… cosa sto ignorando ?!

Mi sfugge ancora qualche cosa. Hai provato con qualche cosa del tipo:




if(!$model->save()) {

    echo $mode->errors();

}



Non ricordo se errors è un metodo o un attributo, però può aiutarci a capire se "passa" questo metodo.

Un altra cosa da controllare è questa: mi è capitato di creare dei model e successivamente di modificare il tipo di dato. Nel model era, per esempio, impostato ‘integerOnly’ => true mentre io cercavo di inserire un valore alfanumerico. Il risultato finale si riconduceva sempre a “0”.

Le variabili settate non fanno parte degli attributi,

che vengono generati in base al db e inseriti nell’array _attributes

La variabile esterna rimane settata, giustamente, ma non inserita nell’array, perciò $model->attributes non funziona (mi pare che la funzione SetAttributes richiamata cicli i valori dell’array e prenda solo quelli già presenti)

Per settare la voce devi farlo direttamente. (o perlomeno io faccio così, se troviamo soluzioni migliori meglio :) )

Accidenti, è vero, in passato mi ero già imbattuto in questa cosa…

Però ora che ho sperimentato volevo farvi sapere che

  • durante il set ‘massivo’ tutte le proprietà vengono settate. … ma

  • … NON vengono lette da model->attributes …

  • … ma SONO VALORIZZATE correttamente quindi $model->nome_variabile viene letta bene

Ma LOL =)

eh, già, piccola incoerenza… stavo pensando di creare uno snippet e segnalare al cosa su github al core team di Yii, ma se qualcuno più esperto di me lo volesse fare …

Nessuna incoerenza. Molto semplicemente va bene così =). Non puoi usare del codice aspettandoti da lui cose che non deve fare.

beh, qui è solo una mia opinione, ma se il setAttribute li ‘maneggia’ tutti, non capisco perchè il getAttribute no, tutto qua.

Probabilmente c’è un modo per inserire la nostra variabile aggiunta negli attributi, visto che CActiveRecord non ve la inserisce di default…

E’ questo il punto: non state seguendo l’Active Record: va aggiunto un campo al database.

Magari sbaglio io, però tu fai il get di un attributo in un model che non ha quell’attributo nella tabella?

si, effettivamente è così. . . forse ho capito

Ma se io ho bisogno si settare una variabile della classe che non va nel db?

Bene, puoi scrivere tranquillamente i tuoi getter e setter. Però esci dalla logica del ActiveRecord secondo me. Vedi tu. Dovrai importare gli attributi in un modo quando fanno parte della tabella e quell’attributo dovrà/potrà essere calcolato. Io posso capire quando viene generato un form, ma come fai a recuperare quel dato per esempio in una view? Come lo recuperi?

Ci sono moltissimi casi in cui si ha bisogno di avere un campo esterno al DB nella vita reale.

Ho un modulo di invio di dati, che prevede dei modelli presalvati, quindi il 99% dei dati è precaricato.

Potrei farmi un CFormModel, ma effettivamente mi raddoppia il lavoro, allora faccio la form basata su un ActiveRecord ed aggiungo solo un paio di campi che cambiano ad ogni submit ma non devo salvarli.

Questo giusto per fare un esempio.

Comunque è decisamente mooooolto possibile che data l’esperienza non pluriennale con Yii io abbia sbagliato approccio, però non posso, tutte le volte, riscrivere parti intere dell’app. Sarà per la prossima, tanto se ne sforna una nuova ogni tre mesi.

Il caso è interessante. Se poi mi dici che ti può capitare spesso, analizziamo meglio il problema e troviamo una soluzione una volta per tutte. Magari con un wiki o altro. Però a me in questo momento sfugge la necessità di avere un form con dati che non devono essere salvati.