Active Record Without Primary Key

Hi there,

I’d like to ask you how do you update/delete an active record without primary key?

I arrived to this problem from the necessity to deal with MANY_MANY relationship. I tried a package yii-cmanymanyactiverecord but it turned out to not work properly for my simple case. Therefore I decided to create an Active Record that manages this type of relation between my models Articles and Keywords with the following undelying DB structure


class m130907_183909_articles_keywords extends CDbMigration

{

	public function up()

	{

         $this->createTable('articles_keywords', array(

            'article_id' => 'integer NOT NULL',

            'keyword_id' => 'integer NOT NULL',

        ));

		$this->addForeignKey('reference_to_article', 'articles_keywords', 'article_id',

			'articles', 'id', 'RESTRICT', 'RESTRICT');

		$this->addForeignKey('reference_to_keyword', 'articles_keywords', 'keyword_id',

			'keywords', 'id', 'RESTRICT', 'RESTRICT');

		echo 'the table articles_keywords along with the FKs has been created succesefully';

	}

.....

}



Everything went fine until I came to BDD when I wanted to flush the content of my test DB:


  public static function prepare(){

        $models = ArticlesKeywords::model()->findAll();

        foreach ($models as $item) {

            echo $item->article_id, ' - ' , $item->keyword_id, PHP_EOL;

            try {

                $item->delete(); 

            } catch (Exception $e) {

                echo 'error: ', $e->getMessage();

            }

       }

}

Strange enough, the active records are found, their attributes are displayed, but when it comes to $item->delete() I’ve got the error


Column name must be either a string or an array.

The simplest way out would be just to add a primary key, but I’d like to not “pollute” the model with unnecessary attributes.

Therefore I would like to ask you how would you deal with such a sitation?

You should define a composite primary key from both columns in that table.

Fantastic! It now works without inventing additional methods. Following your advice my migration now looks like




class m130907_183909_articles_keywords extends CDbMigration{

    public function up()

	{

            $this->createTable('articles_keywords', array(

            'article_id' => 'integer NOT NULL',

            'keyword_id' => 'integer NOT NULL',

            'PRIMARY KEY (`article_id`, `keyword_id`)'

        ));

		$this->addForeignKey('reference_to_article', 'articles_keywords', 'article_id',

			'articles', 'id', 'RESTRICT', 'RESTRICT');

		$this->addForeignKey('reference_to_keyword', 'articles_keywords', 'keyword_id',

			'keywords', 'id', 'RESTRICT', 'RESTRICT');

		echo 'the table articles_keywords along with the FKs has been created succesefully';

	}

........

}