【问题标题】:Yii 2: how to build search query using ActiveRecord between 2 tables?Yii 2:如何在 2 个表之间使用 ActiveRecord 构建搜索查询?
【发布时间】:2015-03-03 11:35:17
【问题描述】:

我用的是 Yii 2。

要明确:

  • content和task这两个表是1:1的关系,task.content_id = 内容.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?

感谢您的帮助。

【问题讨论】:

  • 任务和内容是1:1的关系?您是否将 GridView 用于您的任务并同时显示内容?现在您想让内容也可搜索吗?如果是这样,请更新您的帖子以说明这一点。

标签: activerecord yii2


【解决方案1】:

你可以试试这个:

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

【讨论】:

    【解决方案2】:

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

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

    我想这可能会对你有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-03
      • 1970-01-01
      • 2017-05-07
      • 1970-01-01
      • 2021-12-02
      • 2019-07-28
      • 1970-01-01
      • 2022-10-09
      相关资源
      最近更新 更多