【问题标题】:yii2 - filtering model by default with joined tableyii2 - 默认情况下使用连接表过滤模型
【发布时间】:2017-01-25 22:17:53
【问题描述】:

我在 Yii2 中积极开发。我有一个问题。我没有找到任何相关信息。

我关于默认过滤模型的问题。 例如,我有一个类别和分配给类别的项目。并不是任何用户都可以访问所有类别。在创建类别时,您可以选择为用户设置访问权限。

那么,如何为类别模型设置全局过滤器?那,无论我在哪里请求类别列表 - 我都会根据用户访问权限接收它。当然我可以编写自己的方法而不是 find() ->, findAll() ...但也许还有另一种解决方案,对 yii2 更规范

感谢您的帮助!

更新 #1

使用覆盖 find() 方法的 Sulotion。但是 validateAttributes() 方法有问题

public static function find()
{
    $query = new ProjectsQuery(get_called_class());

    $query->alias('p')
        ->leftJoin(ProjectsAccessibility::tableName().' pa','pa.project_id=p.id')
        ->andWhere(['like','pa.user_id',Yii::$app->user->id]);

    return $query;
}

更新 #2

使用 joinCondition() 但仍然捕获1052 Column 'id' in where clause is ambiguous

public static function find()
{
    $query = new ProjectsQuery(get_called_class());

    $query->joinWith([
        'projectsAccessibility' => function($query){
            $query->onCondition(['user_id' => Yii::$app->user->id]);
        },
    ]);

    return $query;
}

更新 #3

让我更详细地解释一下我的问题。我正在创建一个项目经理系统。因此,我列出了分配给项目的 项目任务。 还有一张表,其中包含用户和项目之间的访问信息:

Projects
id | name
1    Project 1
2    Project 2

Tasks
id | project_id | name
1          1      Task 1 
2          2      Task 2

Users
id | name
1    User 1 
2    User 2

Project Access
id | user_id | project_id
1      2           1
2      2           2 
3      1           1

所以,我想做的是根据授权的 user_id 显示项目和任务列表,它现在正在工作。但是当我用连接表覆盖 find() 方法时,当我尝试创建一个新任务时出现 mysql 错误,因为在 save() yii2 检查所有属性是否存在,但它不知道 find() 方法中的连接表与相同列名 - id

完整的错误信息:

SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous
The SQL being executed was: SELECT EXISTS(SELECT tm_projects.* FROM tm_projects LEFT JOIN tm_projects_accessibility ON (tm_projects.id = tm_projects_accessibility.project_id) AND (user_id=37) WHERE id='1')

【问题讨论】:

    标签: model yii2 filtering


    【解决方案1】:

    您始终可以在模型类中覆盖 find() 方法:

    public static function find()
    {
        return parent::find()->onCondition(['owner_id' => Yii::$app->user->id]);
    }
    

    或者,如果您已经覆盖它以使用 ActiveQuery 类,例如:

    public static function find()
    {
        return new \app\models\CategoryQuery(get_called_class());
    }
    

    然后你可以使用该类的init() 方法来定义默认过滤器:

    class CategoryQuery extends \yii\db\ActiveQuery
    {
        public function init()
        {
            $this->andOnCondition([['owner_id' => Yii::$app->user->id]]);
            parent::init();
        }
    }
    

    【讨论】:

    • 在您使用连接表的情况下,我在创建项目期间遇到了 validateAttributes() 方法的问题。 A got error Integrity constraint violation: 1052 Column 'id' in where clause is ambiguous in query SELECT EXISTS(SELECT p.* FROM tm_projects p LEFT JOIN tm_projects_accessibility pa ON pa.project_id=p.id WHERE (pa.user_id LIKE '%37%') AND (id='6')) Overrided find method you can find in my updated post
    • 更新了我的帖子。当我尝试创建新项目 1052 Column 'id' in where clause is ambiguous 时,仍然遇到与 onCondition() 相同的错误。
    • 再次更新我的帖子,提供更多关于我的问题的日期
    • 这是一个不同的问题。见official docs on how to implement relational data when using ActiveRecord。我认为您将其与Query Builder 混合在一起。检查this SO post了解更多详情。它与 Yii1 相关,但同样适用于 Yii2。使用查询生成器时,您会获得性能,但会失去 AR 功能。
    猜你喜欢
    • 2014-08-21
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 2020-01-31
    • 2016-02-10
    相关资源
    最近更新 更多