How Data Be Shared By Two Models?

Hello everyone, I have a problem about the data sharing between two models.

For example, I got a Content model and an Article model. After created a content record, the application will redirect user to Article create page, and I want to auto-display the content name attribute and content id that I have just created in the Article create form. However, I don’t how to pass the name and id from Content model to Article model. Please help, thank you.

Hi Pan_mamkkl, welcome to the forum!

Can you show us how Contnet and Article are related? I mean, have you established a relation between the 2 models like "Article BELONGS_TO Content" or something like that?

Thank you softark. Yes, I have established the relationship between Article and content in database also in corespondent model.

in the Article model, I have set up the relations().


public function relations()

	{

		return array(

			'idContent' => array(self::BELONGS_TO, 'Content', 'id_content'),

		);

	}

and also the Content model


public function relations()

	{

		return array(

			'articals' => array(self::HAS_MANY, 'Artical', 'id_content'),

		);

	}

the user will first create a content record then redirected to Article to create an article.

I see.

When you have successfully created a Content, you can get the ID of it. Then you can call some action to create an Article with the ID of the content.




// ContentController.php

...

public function actionCreate()

{

    ...

    if ($model->save()) {

        $this->redirect(array('article/createForContent', 'id_content' => $model->id));

    }

    ...

}



And in the customized create action, you can set ‘id_content’ of the Article. It will ensure the created article will belong to the content.

You can optionally load the content model and show its name or anything in the create view.




// ArticleController.php

...

public function actionCreateForContent($id_content)

{

    $model = new Article;

    $model->id_content = $id_content;

    $content = Conent::model()->findByPk($id_content);


    // AJAX validation

    $this->performAjaxValidation($model);


   if (isset($_POST['Article'])) {

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

       if ($model->save()) {

           $this->redirect(array('view', 'id'=>$model->id));

       }

   }

   $this->render('createForContent', array(

      'model' => $model,

      'content' => $content,

   ));

}



Thank you so much. I want to ask more, hope you won’t mind:).

  1. The createForContent is an customize action, but where should I call it? I know the default action like view will call the default action actionView but for createForContent where can I specify/change/create the function call to due with the createForContent request?

  2. at last it pass model and content as the data, so it will display both model and content within a form?

  1. I don’t understand clearly what you are asking, but “actionCreateForContent” method in “ArticleController” class implements “article/createForContent” action.

http://www.yiiframework.com/doc/guide/1.1/en/basics.controller

  1. Yes, you are right.

$model is an Article model and its content is not retrieved from the database table. It’s used for form input.

And $content is for the Content model. It will display the name of the content in the form if you use it for a plain text. (As we don’t handle the input for Content in this action, we can not create an input for $content model in the form.)

I understand, however when I modify the code in the way that you recommend, it pause with an error with code 403 said ‘You are not authorized to perform this action.’ Am I miss something?

OK, I have fix the permission problem. Thank you.

But I am facing to another problem, how to use the content object that I have passed to article? I use call it in _form, which is belong to Article, like this


<div class="row">

	<?php echo $form->labelEx($content,'create_by'); ?>

	<?php echo $form->textField($content,'create_by'); ?>

	<?php echo $form->error($content,'create_by'); ?>

</div>

But it said $content is non-object.

Maybe you are calling the action with an invalid content_id.

Check if $content is not null after you have called "$content = Content::model()->findByPk($id_content)".

And what I have written is just a sample in order to illustrate how to pass the id of a model to another action and get the model in that action. It’s not a recommendation or something that you SHOULD follow.

BTW, do you want to update the Content model together when you create an Article for it? If so, then you want to read this wiki:

http://www.yiiframework.com/wiki/19/how-to-use-a-single-form-to-collect-data-for-two-or-more-models