php – 关系Yii ActiveRecord用于具有NULL值的复合键的表
为了在某??些站点上存储用户定义的书签,我有一个包含复合键的表:
CREATE TABLE bookmarks ( user_id int not null,book_id int not null,page_id int,... ); CREATE UNIQUE INDEX ON bookmarks(user_id,book_id,page_id); 注意,page_id可以为NULL,而user_id和book_id则不能.当page_id为null时,为整本书设置书签,否则 – 为某个页面设置. 对应的ActiveRecord类定义了一些关系: public function relations() { return array( "user" => array(self::BELONGS_TO,"User","user_id"),"book" => array(self::BELONGS_TO,"Book","book_id"),"page" => array(self::BELONGS_TO,"Page","page_id"),); } 和一个primaryKey()方法:: public function primaryKey() { return array("user_id","book_id","orig_id"); } 现在我想为一些用户获取整本书的所有书签.所以,我这样做: $bookmarks = Bookmark::model()->findAll(array( "condition" => "t.user_id = :user_id AND t.page_id IS NULL","params" => array(":user_id" => 1),)); 它运行良好,返回4条记录,但显然,我想使用书籍表中的一些相关数据: $bookmarks = Bookmark::model()->findAll(array( "with" => "book","condition" => "t.user_id = :user_id AND t.page_id IS NULL",)); 现在我得到0条记录(count($bookmarks)== 0),虽然生成的SQL语句选择了所有需要的数据,但它只是不被CActiveRecord类识别.另一个奇怪的是,当我尝试获取所有页面书签时,一切都很好: $bookmarks = Bookmark::model()->findAll(array( "with" => "book","condition" => "t.user_id = :user_id AND t.page_id IS NOT NULL",)); 我究竟做错了什么?如何在第二个例子中使表达式返回一些数据? PHP 5.4.0,Yii 1.1.8,PostgreSQL 9.1.4,外部32°C. 解决方法
您的问题可以通过这种方式解决:
>将代理PK添加到书签表(例如自动增量序列). 您也可以使用更方便的代码: public function relations() { return array( //... 'wholeBook' => array(self::BELONGS_TO,'Book','book_id','on'=>"page_id IS NULL",'joinType'=>'INNER JOIN'),//... ); } 然后在控制器中: $bookmarks = Bookmark::model()->with('wholeBook')->findAllByAttributes(array('user_id'=>1)); 事实上,使用UNIQUE键而不是PRIMARY和primaryKey(),您可以使用hack来避免在复合PK中使用NULL列的不可能性. 如果我是你,我会将SQL标准化为以下内容: 因为这是两种不同类型的书签,具有不同的关系.您应该只在视图逻辑中加入它们,而不是在关系结构中.恕我直言 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |