Column disambiguation on named scopes

I want to suggest a feature in general, but i don’t have a clear view of how this could be implemented, i will try to explain the problem and let other people suggest a implementation:

Suppose i got 2 tables and their models, Post and Comment. Comments are related to Posts by the ‘idpost’ column and both tables got a ‘is_published’ column, and the Comment model got a published ‘published’ scope.

So in Post model i got:




class Post {

...

   public function relations() {

      return array('comments'=>array(self::HAS_MAY, 'Comment', 'idpost'));

   }

}



And in Comment model i got:




class Comment {

...

   public function scopes() {

      return array(

         'published'=>array('condition'=>'is_published=1')

      );

   }

}



If in some part of my application i try something like this:




Post::model()->with('comments:published')->find();



It will cause a SQL error due to the ambiguous collumn name ‘is_published’. Using the ‘t.is_published’ in the named scope will break the named scope in relational query (since ‘t’ is the alias of the main table, in this case post table), and by the other hand hard coding the relation name in the named scope breaks the code in no-relational queries and in other relations.

By this time my workaround is simple not use named scopes in relational queries, but since its a great feature with growing use i think this kind of problem will become more and more common.

Thanks,

Eduardo P de Sousa

PS: I solution that occurred me now is enforce the prefix ‘t’ in named scopes, and code a feature in Yii to during the query construction, check the table alias and do the replacements. I’m not sure if its possible or will work, just a idea.

you make this




class Comment {

...

   public function scopes() {

      $alias = $this->getTableAlias();

      return array(

         'published'=>array('condition'=>$alias.'.is_published=1')

      );

   }

}



then $alias value will be have a relation name, (comments in your example)

then you call like this




Comment::model()->published()->findAll();



$alias have value t

If you use this in your defaultScope() you need to make sure it doesn’t go into a recursive loop by:




$a = $this->getTableAlias( false, false );