Proper way to modify $model->attribue before rendering ActiveForm

I have a MongoDb collection with an array as one of it’s fields and I have a \mongodb\ActiveRecord model for it. So after loading, a model has an array as its attribute. Then I need to render the model into ActiveForm. I decided to render elements of the array into textarea devided by new line, so I need to


implode('\r\n', $model->attr)

before passing $model into ActiveForm widget.

The question is where it is the right place for this?

Right now I’m doing implode in the controller (actionCreate and actionUpdate twice)


if (is_array($model->attr)) {

  $model->attr = implode("\r\n", $model->attr);

}

and explode in ActiveRecord::beforeSave()


if (is_string($this->attr)) {

    $ar = explode("\r\n", trim($this->attr));

    $this->attr = array_map('trim', $ar);

}

but it feels wrong to me.

I’d like to tie this behavior to AcriveForm before it renders and after it is submitted, but I don’t see such methods.

Hi Bombero:

The best place to handle this is in the init method of the Form model like so:




class AddressChangeForm extends Model

{	

	public $address1;

	public $address2;

	public $city;

	public $state;

	public $zip;

	public $verify_code;

			

	public function init()

	{

		parent::init();

	        //See here I am setting up the model BEOFRE the form is rendered so that when the form is rendered

                //it will have the values

		$parent = Yii::$app->user->getIdentity(); 

		$address = ParentsAddress::find()->where('parent_id = '.$parent->parent_id)->one();

		$this->address1 = $address->address1;

		$this->address2	= $address->address2;

		$this->city = $address->city;

		$this->state = $address->state;

		$this->zip = $address->zip;

	} 		

}



And AFTER the form has been submitted you could handle the conversion in a number of ways;

  1. A custom method in the Active form model. For example in that class above I have a method called "update_address":



public function update_address()

{

	$parent = Yii::$app->user->getIdentity(); 

	$address = ParentsAddress::find()->where('parent_id = '.$parent->parent_id)->one();

		

	$address->address1 = $this->address1;

	$address->address2 = $this->address2;

	$address->city = $this->city;

	$address->state = $this->state;

	$address->zip = $this->zip;	

	$address->update();

}



And then in my controller the code looks like this:




public function actionAccount()

{

    $address_model = new AddressChangeForm();


    if($address_model->load(Yii::$app->request->post())){

	  if($address_model->validate())

		$address_model->update_address();

    }


   return $this->render('account',['address_model' => $address_model]);

}



]

Also if you’re using a straight ActiveRecord --> to – Form just use the ActiveRecord’s “beforeSave()” method to convert the array before writing to the database. See here for details: http://www.yiiframework.com/doc-2.0/yii-db-baseactiverecord.html#beforeSave()-detail