Yii 2:如何在 2 个表之间使用 ActiveRecord 构建搜索查询?
Yii 2: how to build search query using ActiveRecord between 2 tables?
我用的是 Yii 2.
要明确:
- 内容和任务这两个table是1:1关系,task.content_id =
content.id;
- 我参考了
doc.
- 在视图文件中,我使用了Gridview来显示数据。
- 而且我希望内容也可以搜索到,即使它在另一个
table.
也许下面的sql可以解释我想要的:
SELECT
c.content,
t.publish_status
FROM
content c, task t
WHERE
c.content LIKE '%keywordInContent%' AND
t.publish_status = 1 AND
c.id = t.content_id
ORDER BY
updated_at
LIMIT 20;
这是我的控制器代码:
public function actionIndex()
{
$searchModel = new TaskSearch;
$dataProvider = $searchModel->search(Yii::$app->getRequest()->get());
return $this->render('index', [
'dataProvider' => $dataProvider,
'searchModel' => $searchModel,
]);
}
并搜索型号代码:
public function search($params)
{
$query = Task::find()->trashed(Task::TRASHED_NO);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
$query->andFilterWhere(['publish_status' => $this->publish_status]);
return $dataProvider;
}
我已经通过搜索 like 子句并将结果 content_id 添加到 searchModel 查询来解决它,代码如下:
if (!empty($this->keyword)) {
$contentIdArr = Content::find()->select('id')->where(['like', 'content', $this->keyword])->column();
if (empty($contentIdArr)) {
$contentIdArr = -1;
}
$query->andFilterWhere(['content_id' => $contentIdArr]);
}
我想知道有没有一种方法可以构建我在 Yii 2 begin 中写的 sql?
感谢您的帮助。
我认为你可以通过首先获取内容数据并与任务模型建立关系来做到这一点。
你可以通过这个link建立关系。 内容 模型中的关系:
public function getTask()
{
return $this->hasOne(Task::className(), ['content_id' => 'id']);
}
和搜索查询
$searchResult = Content::find()
->select('content, publish_status')
->with('task')
->where(['LIKE', 'content', 'keywordInContent'])
->andWhere(['publish_status' => 1])
->orderBy('updated_at')
->limit(20)
->all();
我认为这可能对您有所帮助。
你能试试这个吗:
public function search($params)
{
$query = Task::find()->trashed(Task::TRASHED_NO);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
if(!empty($this->keyword))
$query->leftJoin('content', 'content.id=task.content_id')
->andWhere(['publish_status' => 1])
->andWhere(['LIKE', 'content', $this->keyword])
->orderBy('updated_at');
return $dataProvider;
}
但是 updated_at 不应该是搜索的一部分,我想。这更多是关于排序。查看 here 示例。
我用的是 Yii 2.
要明确:
- 内容和任务这两个table是1:1关系,task.content_id = content.id;
- 我参考了 doc.
- 在视图文件中,我使用了Gridview来显示数据。
- 而且我希望内容也可以搜索到,即使它在另一个 table.
也许下面的sql可以解释我想要的:
SELECT
c.content,
t.publish_status
FROM
content c, task t
WHERE
c.content LIKE '%keywordInContent%' AND
t.publish_status = 1 AND
c.id = t.content_id
ORDER BY
updated_at
LIMIT 20;
这是我的控制器代码:
public function actionIndex()
{
$searchModel = new TaskSearch;
$dataProvider = $searchModel->search(Yii::$app->getRequest()->get());
return $this->render('index', [
'dataProvider' => $dataProvider,
'searchModel' => $searchModel,
]);
}
并搜索型号代码:
public function search($params)
{
$query = Task::find()->trashed(Task::TRASHED_NO);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
$query->andFilterWhere(['publish_status' => $this->publish_status]);
return $dataProvider;
}
我已经通过搜索 like 子句并将结果 content_id 添加到 searchModel 查询来解决它,代码如下:
if (!empty($this->keyword)) {
$contentIdArr = Content::find()->select('id')->where(['like', 'content', $this->keyword])->column();
if (empty($contentIdArr)) {
$contentIdArr = -1;
}
$query->andFilterWhere(['content_id' => $contentIdArr]);
}
我想知道有没有一种方法可以构建我在 Yii 2 begin 中写的 sql?
感谢您的帮助。
我认为你可以通过首先获取内容数据并与任务模型建立关系来做到这一点。
你可以通过这个link建立关系。 内容 模型中的关系:
public function getTask()
{
return $this->hasOne(Task::className(), ['content_id' => 'id']);
}
和搜索查询
$searchResult = Content::find()
->select('content, publish_status')
->with('task')
->where(['LIKE', 'content', 'keywordInContent'])
->andWhere(['publish_status' => 1])
->orderBy('updated_at')
->limit(20)
->all();
我认为这可能对您有所帮助。
你能试试这个吗:
public function search($params)
{
$query = Task::find()->trashed(Task::TRASHED_NO);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
if(!empty($this->keyword))
$query->leftJoin('content', 'content.id=task.content_id')
->andWhere(['publish_status' => 1])
->andWhere(['LIKE', 'content', $this->keyword])
->orderBy('updated_at');
return $dataProvider;
}
但是 updated_at 不应该是搜索的一部分,我想。这更多是关于排序。查看 here 示例。