我们正在尝试以用户只能检索与其帐户相关的数据的方式设置REST API。现在停止,我们只有一个公共API,它都像一个魅力。 公共API仍将被使用,因此我们从头开始。
我们有User
模型,扩展ActiveRecord
并实施IdentityInterface
。用户将与Customer
模型有关系(许多:很多,但至少有一个)。用户将拥有only one MASTER
客户。
以上内容使用3个表app_customer_users
,app_customers
和link_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_id
或Yii::$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 ..
答案 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;