Applying A Defaultscope To A Model Based On The Attribute Of A Related Model

Hi guys. Noob here.

I am trying to figure out how trim all my listings of models. Trying to use defaultScope but running into problems and wondering if it’s the right way to go.

The 3 pertinent models are User, Project and Task:




class User extends CActiveRecord

{

    public function relations()

    {

        return array(

            'projects' => array(self::HAS_MANY, 'Project', 'project_id'),

        );

    }

}


class Project extends CActiveRecord

{

    public function relations()

    {

        return array(

             'tasks' => array(self::HAS_MANY, 'Task', 'project_id'),

             // This is always the user->id of the person who created the project

             'user' => array(self::BELONGS_TO, 'User', 'user_id'),

        );

    }

}


class Task extends CActiveRecord

{

    public function relations()

    {

        return array(

	    'project' => array(self::BELONGS_TO, 'Project', 'project_id'),

        );

    }

}



I would like the default behavior of the Project to be that it only shows the projects created by the logged in user. So I added a defaultScope to it like so:




class Project extends CActiveRecord

{

    ...

    

    public function defaultScope() 

    {

        $user_id = Yii::app()->user->id ? Yii::app()->user->id : 0;

        $alias = $this->tableName();


        return array(

            'alias' => $alias,

            'condition' => "`$alias`.`user_id`=" . $user_id,

        );

    }

}



That works great. But I want the same behavior for the Task model. I want to only show Tasks related to a Project that was created by the currently logged in user. I’ve tried a lot of things, but this should give you an idea of what I thought would work:




class Task extends CActiveRecord

{

    public function defaultScope() 

    {

        $user_id = Yii::app()->user->id ? Yii::app()->user->id : 0;

        $alias = Project::model()->tableName();

        

        return array(

            'with' => array(

                'project' => array(

                    'alias' => $alias,

                    'condition' => "`$alias`.`user_id`=" . $user_id,

                ),

            ),

        );

    }

}



I’ve tried fiddling with the alias and the condition but I always get an exception similar to:




CDbCommand failed to execute the SQL statement: SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'projects'. The SQL statement executed was: SELECT `projects`.`id` AS `t0_c0`, `projects`.`name` AS `t0_c1`, `projects`.`description` AS `t0_c2`, `projects`.`created` AS `t0_c3`, `projects`.`modified` AS `t0_c4`, `projects`.`department_id` AS `t0_c5`, `projects`.`status_id` AS `t0_c6`, `projects`.`user_id` AS `t0_c7`, `tasks`.`id` AS `t1_c0`, `tasks`.`name` AS `t1_c1`, `tasks`.`description` AS `t1_c2`, `tasks`.`created` AS `t1_c3`, `tasks`.`modified` AS `t1_c4`, `tasks`.`project_id` AS `t1_c5`, `projects`.`id` AS `t2_c0`, `projects`.`name` AS `t2_c1`, `projects`.`description` AS `t2_c2`, `projects`.`created` AS `t2_c3`, `projects`.`modified` AS `t2_c4`, `projects`.`department_id` AS `t2_c5`, `projects`.`status_id` AS `t2_c6`, `projects`.`user_id` AS `t2_c7` FROM `projects` `projects` LEFT OUTER JOIN `tasks` `tasks` ON (`tasks`.`project_id`=`projects`.`id`) LEFT OUTER JOIN `projects` `projects` ON (`tasks`.`project_id`=`projects`.`id`) AND (`projects`.`user_id`=12) WHERE (`projects`.`user_id`=12) AND (`projects`.`user_id`=12) 



Is my approach ever going to work or do I need to rethink my whole process?

Thanks,

Brendan