yii2添加' 0 = 1'查询多对多关系

时间:2015-09-05 14:30:22

标签: mysql many-to-many yii2 relation

我有一个项目,用户必须彼此联系 - 就像朋友一样。所以我决定将它们连接到桌面上' connect'。看起来像是它的权利。但是,当我试图搜索朋友请求时,我得到了错误,如下所述。 这是我的模特用户:

<?php namespace common\models
use dektrium\user\models\User as BaseUser;
use Yii;
use yii\data\ActiveDataProvider;
use yii\helpers\ArrayHelper;
use dosamigos\taggable\Taggable;
use yii\db\ActiveQuery;
/**
* User model
*
* @inheritdoc
* @property string $search
* @property string $category
*
* @property ActiveQuery $requests
*/
class User extends BaseUser
{
#region Properties
public $category;
public $search;

const SCENARIO_CATEGORY = 'category';
const SCENARIO_SEARCH = 'search';
#endregion

#region Yii
/**
* @inheritdoc
*/
public static function tableName()
{
return '{{%user}}';
}

/**
* @inheritdoc
*/
public function rules()
{
return array_merge(parent::rules(), [
[['category'], 'safe', 'on' => self::SCENARIO_CATEGORY],
[['search'], 'safe', 'on' => self::SCENARIO_SEARCH],
]);
}

/**
* @inheritdoc
*/
function scenarios()
{
return array_merge(parent::scenarios(), [
self::SCENARIO_CATEGORY => ['category'],
self::SCENARIO_SEARCH => ['search']
]);
}
#endregion

#region Callbacks
function afterFind()
{
$this->category = implode(', ', ArrayHelper::map($this->getCategories()->asArray()->all(), 'id', 'name'));
parent::afterFind();
}

/**
* @inheritdoc
*/
public function behaviors()
{
return array_merge(parent::behaviors(), [
[
'class' => Taggable::className(),
'attribute' => 'category',
'relation' => 'categories',
]
]);
}
#endregion

#region Relations
/**
* @return \yii\db\ActiveQuery
*/
function getCategories()
{
return $this->hasMany(Category::className(), ['id' => 'category_id'])->viaTable('{{%category_user}}', ['user_id' => 'id']);
}

/**
* @return \yii\db\ActiveQuery
*/
function getRequests()
{
return $this->hasMany(User::className(), ['id' => 'user_two'])->viaTable(Connection::tableName(), ['user_one' => 'id']);
}
#endregion

#region Methods
function search($params)
{
$query = self::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);

//        if (!$this->validate()) {
//            $query->where('0=1');
//            return $dataProvider;
//        }

$query->joinWith(['categories']);

$query->andFilterWhere(['like', 'category.name', $this->search]);

return $dataProvider;
}

function isConnected($user_id)
{
return Connection::isConnected(Yii::$app->user->id, $user_id);
}

function requestCount()
{
return Connection::requestCount(Yii::$app->user->id);
}

function requestPends()
{
$query = $this->getRequests();

$result = new ActiveDataProvider([
'query' => $query
]);

$query->joinWith(['requests']);
$query->from(User::tableName() . ' u1');
$query->where = "";
$query->andFilterWhere(['connection.status' => Connection::STATUS_PENDED]);

return $result;
}
#endregion
}

这是我的连接模型:     

namespace common\models;

use Yii;
use yii\data\ActiveDataProvider;
use yii\db\Query;

/**
* This is the model class for table "connection".
*
* @property integer $id
* @property integer $user_one
* @property integer $user_two
* @property integer $status
*
* @property User $userOne
* @property User $userTwo
*/
class Connection extends \yii\db\ActiveRecord
{
const STATUS_PENDED = 0;
const STATUS_ACCEPTED = 1;
const STATUS_DENIED = 2;

public static function primaryKey()
{
return array('id');
}

/**
* @inheritdoc
*/
public static function tableName()
{
return 'connection';
}

/**
* @inheritdoc
*/
public function rules()
{
return [
[['user_one', 'user_two', 'status'], 'integer'],
[['user_one'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['user_one' => 'id']],
[['user_two'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['user_two' => 'id']],
];
}

/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'user_one' => Yii::t('app', 'User One'),
'user_two' => Yii::t('app', 'User Two'),
'status' => Yii::t('app', 'Status'),
];
}

/**
* @return \yii\db\ActiveQuery
*/
public function getUserOne()
{
return $this->hasOne(User::className(), ['id' => 'user_one']);
}

/**
* @return \yii\db\ActiveQuery
*/
public function getUserTwo()
{
return $this->hasOne(User::className(), ['id' => 'user_two']);
}

function search($params)
{
$query = self::find();
$result = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
//        if (!$this->validate()) {
//            $query->where('0=1');
//            return $result;
//        }
return $result;
}

static function isConnected($user_one, $user_two)
{
return self::find()->where('(user_one=:one AND user_two=:two) OR ((user_one=:two AND user_two=:one))', [':one' => $user_one, ':two' => $user_two])->andFilterWhere(['status' => Connection::STATUS_ACCEPTED])->count();
}

static function requestCount($user_id)
{
return (int)self::find()->where(['user_two' => $user_id])->andFilterWhere(['status' => Connection::STATUS_PENDED])->count();
}
}

请求视图:

<div class="panel panel-default">
<div class="panel-body">
<?php
//        if ($mdlUser->requestCount()) {
echo ListView::widget([
'dataProvider' => $mdlUser->requestPends(),
'itemView' => '_list',
]);
//        }
?>
</div>
</div>

控制器:

function actionFriendRequest()
{
/** @var User $mdlUser */
$mdlUser = Helper::findModel('\common\models\User', Yii::$app->user->id);
return $this->render('request', [
'mdlUser' => $mdlUser
]);
}

但是yii2会像

那样进行查询
`SELECT `u1`.* FROM `user` `u1` LEFT JOIN `connection` ON `u1`.`id` = `connection`.`user_one` LEFT JOIN `user` ON `connection`.`user_two` = `user`.`id` WHERE ((`connection`.`status`=0)) AND (0=1) LIMIT 20`

问题:(0 = 1)来自???

1 个答案:

答案 0 :(得分:1)

看看你的表情:

$mdlUser = Helper::findModel('\common\models\User', Yii::$app->user->id);

您的0=1很可能来自Helper类,findModel方法,您尚未在此处显示。

更新: 还有两个地方0=1可以来自:QueryBuilder.php第1077行和第1226行,这是yii2为LIKE和IN条件处理空字符串/数组的方式。