Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AR Default scope generates WHERE condition in relations. #3565

Closed
radzserg opened this issue May 23, 2014 · 12 comments
Closed

AR Default scope generates WHERE condition in relations. #3565

radzserg opened this issue May 23, 2014 · 12 comments
Assignees
Labels
type:docs Documentation

Comments

@radzserg
Copy link

Right now we have

  public function hasMany($class, $link)
    {
        /** @var ActiveRecordInterface $class */
        /** @var ActiveQuery $query */
        $query = $class::find();

// Some model with default scope (Class User) 
public static function find()
    {
        return parent::find()->where('user.deleted = 0');
    }

therefore when we join model with default scope we have default condition in WHERE instead of ON condition. If we use LEFT join query doesn't work as expected.

SQL example

SELECT COUNT(*) 
FROM `user` LEFT JOIN `document` ON `user`.`id` = `document`.`user_id`
WHERE document.deleted = 0

LEFT JOIN doesn't work in this case cause

@qiangxue
Copy link
Member

This is how it is designed to work. Yii doesn't know when it should magically put WHERE to ON, and it shouldn't do so.

@cebe
Copy link
Member

cebe commented May 23, 2014

you can use onCondition() instead.

@radzserg
Copy link
Author

Yes but in this case I do the following

public function getDocuments()
    {
        $query = $this->hasMany(Document::className(), ['user_id' => 'id']);
        $query->onCondition($query->where);
        $query->where = null;
        return $query;
    }

Doesn't looks great to me

@cebe
Copy link
Member

cebe commented May 23, 2014

I mean in find() you can use onCondition() instead of where()

@radzserg
Copy link
Author

correct, but I still need to remove WHERE condition from result sql
SELECT *
FROM user LEFT JOIN document ON user.id = document.user_id
WHERE document.deleted = 0
such query will work as INNER JOIN if document is empty I will get 0 rows.

@cebe
Copy link
Member

cebe commented May 23, 2014

what code generated you that query? looks wrong to me as document.deleted should be in ON when specified via onCondition.

@radzserg
Copy link
Author

Ok say I have 2 models User and Document. User has default scope
https://github.com/yiisoft/yii2/blob/master/docs/guide/db-active-record.md#default-scope

class User extends ActiveRecord
{
    /**
     * @return \yii\db\ActiveQuery
     */
    public static function find()
    {
        return parent::find()->where('user.deleted = 0');
    }
}


class Document extends ActiveRecord
{
   /**
     * @return \yii\db\ActiveQuery
     */
    public function getUser()
    {
        // yes I can add onCondition here but where will be left
        return $this->hasOne(User::className(), ['id' => 'user_id']);     
    }
}

// then look into hasOne hasMany 
public function hasOne($class, $link)
    {
        $query = $class::find();                   // this will call User::find() and here we get query with default where
        $query->primaryModel = $this;
        $query->link = $link;
        $query->multiple = false;
        return $query;
    }

@cebe
Copy link
Member

cebe commented May 23, 2014

The solution would be to overwrite find() like this:

    public static function find()
    {
        return parent::find()->onCondition('user.deleted = 0');
    }

this will add 'user.deleted = 0' to ON when joining the relation and to WHERE when just finding users. We should add this to the docs.

@cebe cebe reopened this May 23, 2014
@cebe cebe added this to the 2.0 RC milestone May 23, 2014
@cebe cebe added the type:docs label May 23, 2014
@radzserg
Copy link
Author

Thanks!

@samdark
Copy link
Member

samdark commented Aug 25, 2014

@cebe any suggestion about where to document it?

@cebe
Copy link
Member

cebe commented Aug 26, 2014

this is more like a cookbook things than something for the guide...

@cebe cebe modified the milestones: 2.0 RC, 2.0 GA Aug 26, 2014
@samdark samdark removed this from the 2.0 GA milestone Aug 26, 2014
@samdark samdark self-assigned this Aug 26, 2014
@samdark
Copy link
Member

samdark commented Aug 26, 2014

Added as an issue to cookbook repo. Closing this one as we're not going to add it to the guide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:docs Documentation
Projects
None yet
Development

No branches or pull requests

4 participants