With-Related-Behavior Issue

I have a model Company with a HAS_MANY relationship to the CompanyLocationServed model.

In the CompanyController, I process the related CompanyLocationServed model, and add them to the $model->locationsServed attribute. That seems to work fine. Of course, I do not put in the company_id attribute since the Company model has not been saved yet.

When I try to save using with-related-behavior, I get an error about the company_id attribute being blank in the CompanyLocationServed models.

For some reason, the company_id attribute is not being filled in before attempting to save related CompanyLocationServed models ($company-locationsServed). But, another related model, Address ($company->physicalAddress), works and saves perfectly. What could cause this?

Following is my code. I removed everything that isn’t relevant.

Here is the Company model:


/** This is the model class for table "company".

 *

 * The followings are the available columns in table 'company':

 * @property string $id

...

 *

 * The followings are the available model relations:

...

 * @property LocationServed[] $locationsServed

 ...

 */

class Company extends CActiveRecord

{

...

    public function relations()

    {

        return array(

      ...

            'locationsServed' => array(self::HAS_MANY, 'CompanyLocationServed', 'company_id'),

            ...

        );

    }

...

    public function behaviors()

    {

        return array(

            'withRelated' => array(

                'class' => 'ext.wr.WithRelatedBehavior',

            ),

        );

    }

}

Here is the CompanyLocationServed model:


/**

 * The followings are the available columns in table 'company_location_served':

 * @property string $id

 * @property string $company_id

 * @property string $location_id

 * @property integer $radius_miles

 *

 * The followings are the available model relations:

 * @property Company $company

 * @property Location $location

 */

class CompanyLocationServed extends CActiveRecord

{

...

    public function relations()

    {

        return array(

            'company' => array(self::BELONGS_TO, 'Company', 'company_id'),

            'location' => array(self::BELONGS_TO, 'Location', 'location_id'),

        );

    }

...

}



Here is the Location model (maybe not necessary to see):


/**

 * This is the model class for table "location".

 *

 * The followings are the available columns in table 'location':

 * @property string $id

...

 *

 * The followings are the available model relations:

 * @property CompanyLocationServed[] $companyLocationServeds

 */

class Location extends CActiveRecord

{

...

	public function relations()

	{

		// NOTE: you may need to adjust the relation name and the related

		// class name for the relations automatically generated below.

		return array(

			'companyLocationServeds' => array(self::HAS_MANY, 'CompanyLocationServed', 'location_id'),

		);

	}

}

Lastly, this is from the CompanyController:


public function actionCreate()

    {

        $model = new Company;

        $physicalAddress = new Address;


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

        {

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

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

            {

                $physicalAddress->attributes=$_POST['Address'];

                $model->physicalAddress=$physicalAddress;

            }

                

            // add any new locationsServed

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

                $model->locationsServed = $this->addLocationsServed($_POST['locations']);


            // save model

            if ($model->withRelated->save(

                            true, array(

                        'locationsServed',

                        'physicalAddress',

                    )))

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

                    'model' => $model,

                ));

            else

                echo '<pre>'; CVarDumper::dump($model);

        }

        else

        {

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

                'model' => $model,

                'physicalAddress' => $physicalAddress,

            ));

        }

    }

Hi, did you solve the problem?

I think i have the same issue with my models using yii-1.1.14. I tried also the basic model-structure post-comments:


$post = new Post;

        $post->title = 'Post title';

        $post->content = 'Post content';

       


        $comment1 = new Comment;

        $comment1->content = 'Some content 1';

        $comment2 = new Comment;

        $comment2->content = 'Some content 2';


        $post->comments = array($comment1, $comment2);




CREATE TABLE IF NOT EXISTS `comment` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `post_id` int(11) NOT NULL,

  `content` varchar(128) COLLATE utf8_unicode_ci NOT NULL,

  PRIMARY KEY (`id`),

  KEY `post_id` (`post_id`)

) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci


CREATE TABLE IF NOT EXISTS `post` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `title` varchar(128) COLLATE utf8_unicode_ci NOT NULL,

  `content` varchar(128) COLLATE utf8_unicode_ci NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci


ALTER TABLE `comment` ADD FOREIGN KEY ( `post_id` ) REFERENCES `post` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT ;

So the behavior’s saveRelated() method with parameter true fails to validate with error ‘Post cannot be blank’

With parameter false, which ignores validation, everything works.

This could be connected to primary keys and foreign keys.

attaching the var_dumped comment model with true validation parameter:


object(Comment)[40]

  private '_new' (CActiveRecord) => boolean true

  private '_attributes' (CActiveRecord) => 

    array (size=1)

      'content' => string 'Some content 2' (length=14)

  private '_related' (CActiveRecord) => 

    array (size=0)

      empty

  private '_c' (CActiveRecord) => null

  private '_pk' (CActiveRecord) => null

  private '_alias' (CActiveRecord) => string 't' (length=1)

  private '_errors' (CModel) => 

    array (size=1)

      'post_id' => 

        array (size=1)

          0 => string 'Post cannot be blank.' (length=21)

  private '_validators' (CModel) => 

    object(CList)[50]

      private '_d' => 

        array (size=4)

          0 => 

            object(CRequiredValidator)[52]

              ...

          1 => 

            object(CNumberValidator)[53]

              ...

          2 => 

            object(CStringValidator)[54]

              ...

          3 => 

            object(CSafeValidator)[55]

              ...

      private '_c' => int 4

      private '_r' => boolean false

      private '_e' (CComponent) => null

      private '_m' (CComponent) => null

  private '_scenario' (CModel) => string 'insert' (length=6)

  private '_e' (CComponent) => null

  private '_m' (CComponent) => null

and with false validation parameter:


object(Comment)[33]

  private '_new' (CActiveRecord) => boolean false

  private '_attributes' (CActiveRecord) => 

    array (size=3)

      'content' => string 'Some content 1' (length=14)

      'post_id' => string '2' (length=1)

      'id' => string '3' (length=1)

  private '_related' (CActiveRecord) => 

    array (size=0)

      empty

  private '_c' (CActiveRecord) => null

  private '_pk' (CActiveRecord) => string '3' (length=1)

  private '_alias' (CActiveRecord) => string 't' (length=1)

  private '_errors' (CModel) => 

    array (size=0)

      empty

  private '_validators' (CModel) => null

  private '_scenario' (CModel) => string 'update' (length=6)

  private '_e' (CComponent) => null

  private '_m' (CComponent) => null