Yii2:使用多对多关系的值填充模型字段

时间:2018-02-07 11:10:04

标签: rest yii2 many-to-many

我们正在尝试以用户只能检索与其帐户相关的数据的方式设置REST API。现在停止,我们只有一个公共API,它都像一个魅力。 公共API仍将被使用,因此我们从头开始。

我们有User模型,扩展ActiveRecord并实施IdentityInterface。用户将与Customer模型有关系(许多:很多,但至少有一个)。用户将拥有only one MASTER客户。 以上内容使用3个表app_customer_usersapp_customerslink_customer_users_customers保存在数据库中。连接表包含一个布尔字段master

在用户模型中:

public function getCustomers() {
    return $this->hasMany(Customer::className(), ['id' => 'customer_id'])
        ->viaTable('link_customer_users_customers', ['user_id' => 'id']);
}

在客户模型中:

public function getUsers() {
    return $this->hasMany(User::className(), ['id' => 'user_id'])
        ->viaTable('link_customer_users_customers', ['customer_id' => 'id']);
}

如果我们要求所有客户,他们将填充'用户'(如果我们将其添加到extraFields等等),这非常有用。)

新API在身份验证中使用Basic user:pass,我们可以通过调用Yii::$app->user->getIdentity()来获取当前用户对象/身份。

现在的问题

我们希望能够在用户通过调用Yii::$app->user->getIdentity()->customer_idYii::$app->user->getIdentity()->getCustomerId()来获取客户ID时包含客户ID。客户ID应该是{{1}的ID在联接表master中。

我们已尝试将其添加到== true,就像我们之前使用fields关系所做的那样,但在这种情况下它似乎不起作用:

hasOne

我们尝试创建这样的自定义getter:

$fields['customer_id'] = function($model) {
    return $model->getCustomers()->where('link_customer_users_customers.master', true)->one()->customer_id;
}; // probably the where part is our porblem?

最后一次尝试导致错误

public function getCustomerId() {
    return $this->getCustomers()->andFilterWhere(['link_customer_users_customers.master' => true])->one()->customer_id;
}

我们一直在搜索文档和Google上,但没有找到如何执行此操作的示例。

根据接受的答案,我们添加了一些代码。

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'link_customer_users_customers.master' in 'where clause'\nThe SQL being executed was: SELECT * FROM `app_customers` WHERE (`link_customer_users_customers`.`master`=TRUE) AND (`id`='93') 模型中:

User

现在我们可以通过在项目中调用// Include customer always with user public static function findIdentity($id) { return static::findOne($id)->with('customer'); } // Next to `getCustomers()`, added this `hasOne` relation to get only the customer from // which the current user is the master user public function getCustomer() { return $this->hasOne(Customer::className(), ['id' => 'customer_id']) ->viaTable('link_customer_users_customers', ['user_id' => 'id'], function ($query) { $query->andWhere(['master' => 1]); }); } // Getter, just because public function getCustomerId() { return $this->customer->id; } Yii::$app->user->getIdentity()->customer->id等等来获取客户的ID ..

1 个答案:

答案 0 :(得分:1)

您应该添加如下所示的关系,并使用anonymous函数作为viaTable的第三个参数,以添加另一个条件以将master字段检查为true。

public function getMasterCustomerId() {
    return $this->hasOne(Customer::className(), ['id' => 'customer_id'])
    ->viaTable('link_customer_users_customers', ['user_id' => 'id'],function($query){
       $query->andWhere(['master' => 1]);
   });
}

然后您可以将其用于登录用户,如下所示。

Yii::$app->user->identity->masterCustomerId->id;