Yii 2:如何在2个表之间使用ActiveRecord构建搜索查询?

时间:2015-03-03 11:35:17

标签: activerecord yii2

我使用了Yii 2。

要明确:

  • 两个表,即内容和任务,是1:1关系,task.content_id = content.id;
  • 我引用了 doc
  • 在视图文件中,我使用Gridview显示数据。
  • 我希望内容也可搜索,即使它在另一个内容中也是如此 表

也许以下的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中开始编写的sql?

感谢您的帮助。

2 个答案:

答案 0 :(得分:5)

你可以试试这个:

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示例。

答案 1 :(得分:4)

我认为您可以通过首先获取内容数据并与任务模型建立关系来实现。

您可以通过此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();

我认为这可能会对你有帮助。