Yes but it will not work because it is not in the attribute… I dont have a model for the join table.
My foreign key is position_id, and primary key of related table id…
So if I do:
<?php echo CHtml::activeCheckBoxList($model, ‘position_id’, CHtml::listData($positions, ‘id’, ‘name’ ));?>
I get an error that Layout.position_id does not exists…
If I do :
<?php echo CHtml::activeCheckBoxList($model, ‘id’, CHtml::listData($positions, ‘id’, ‘name’ ));?>
The select form works but how to fill in the relations? The blog example is kinda cheating with this as it has a tag column in the Posts table aswell have the tags in the seperate Tags table:
http://www.yiiframework.com/doc/blog/start.design
With me the tables look like:

I am trying this out: http://www.yiiframework.com/forum/index.php?/topic/3479-an-idea-for-handling-many-many-relationships/
But cannot get it working yet…
I put:
in components/ActiveRecord.php
<?php
class ActiveRecord extends CActiveRecord {
private $_rel_attribs;
public function __isset($name) {
echo $relation;
die();
if(isset($this->_rel_attribs[$name])) {
return true;
}
return parent::__isset($name);
}
public function __set($name,$value) {
if($name === 'attributes' && is_array($value)) {
$all_habtm = array();
foreach($this->relations() as $rel_name=>$relation) {
if($relation[0] === self::MANY_MANY) {
$all_habtm[strtolower($relation[1]).'_id'] = $rel_name;
print_r($relation);
die();
}
}
foreach($value as $key=>$val) {
if(isset($all_habtm[$key])) {
$this->_rel_attribs[$key] = $val;
}
}
}
return parent::__set($name, $value);
}
public function __get($name) {
if(isset($this->_rel_attribs[$name])) {
return $this->_rel_attribs[$name];
}
$rel = $this->relations();
foreach($rel as $r=>$data) {
if($data[0]===self::MANY_MANY && $name==strtolower($data[1]).'_id') {
$result = $this->relationshipIds($r);
$this->_rel_attribs[$name] = $result;
return $result;
}
}
return parent::__get($name);
}
}
And in components/behaviors:
<?php
/**
* Deals with many to many relations
*/
class Habtmbehavior extends CActiveRecordBehavior {
public function relationshipIds($relation) {
if(empty($this->owner->primaryKey)) {
return array();
}
$relations = $this->owner->relations();
list($table,$fk1,$fk2) = $this->parseTableDefinition($relations[$relation][2]);
$command=$this->owner->dbConnection->createCommand("SELECT $fk2 FROM $table WHERE $fk1 = {$this->owner->primaryKey}");
$reader=$command->query();
$ids = array();
foreach($reader as $row) {
$ids[] = $row[$fk2];
}
return $ids;
}
public function afterSave() {
foreach($this->owner->relations() as $rel_name=>$relation) {
if($relation[0]!==CActiveRecord::MANY_MANY) {
continue;
}
list($table,$fk1,$fk2) = $this->parseTableDefinition($relation[2]);
print_r( $this->owner->{$fk1});
die();
if(!isset($this->owner->{$fk2})){
continue;
}
$data = $this->owner->$fk1;
if(empty($data)) {
$data = array();
}
list($table,$fk1,$fk2) = $this->parseTableDefinition($relation[2]);
if(!$this->owner->isNewRecord) {
$command=$this->owner->dbConnection->createCommand("DELETE FROM $table WHERE $fk1 = {$this->owner->primaryKey}");
$command->execute();
}
foreach($data as $id) {
$command=$this->owner->dbConnection->createCommand("INSERT INTO $table($fk1,$fk2) VALUES({$this->owner->primaryKey},$id) ");
$command->execute();
}
}
}
private function parseTableDefinition($table_definition) {
preg_match('/([^(]+)\(([^,*]+), ([^)]+)\)/',$table_definition,$matches);
if(count($matches) !== 4) {
throw new CHttpException('404', "unable to parse $table_definition");
}
return array_slice($matches,1);
}
}
And in my model:
<?php
class Layout extends ActiveRecord
{
/**
* The followings are the available columns in table 'Layouts':
* @var integer $id
* @var string $name
* @var string $filename
* @var string $image
* @var string $description
* @var string $modified
* @var integer $theme_id
*/
/**
* Returns the static model of the specified AR class.
* @return CActiveRecord the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* @return string the associated database table name
*/
public function tableName()
{
return 'layouts';
}
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
return array(
array('name','length','max'=>125),
array('filename','length','max'=>125),
array('image','length','max'=>125),
array('name, filename, image', 'required'),
);
}
/**
* @return array relational rules.
*/
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(
'positions' => array(self::MANY_MANY, 'Positions', 'layout_has_positions(position_id, layout_id)'),
'theme' => array(self::BELONGS_TO, 'Themes', 'theme_id'),
'modules' => array(self::HAS_MANY, 'Modules', 'layout_id'),
'pages' => array(self::HAS_MANY, 'Pages', 'layout_id'),
);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'Id',
'name' => 'Name',
'filename' => 'Filename',
'image' => 'Image',
'description' => 'Description',
'modified' => 'Modified',
'theme_id' => 'Theme',
);
}
public function behaviors(){
return array(
'HabtmBehavior' => array(
'class' => 'HabtmBehavior'
)
);
}
}
But it will not set the foreign key’s in the join table.