OctoberCMS - 关联manyToMany的模型查询

时间:2017-03-20 21:07:35

标签: laravel eloquent octobercms laravel-query-builder

我再次向社区寻求帮助...... 情形:

我有两个带有一个数据透视表的表(类似于帖子和标签以提供一些上下文):

    table 1 (Evento):
        -id
        -....

    table 2 (Etiquetas):
        -id
        -etiqueta

    pivot table (Eventos_Etiquetas):
        -evento_id (pk)
        -etiqueta_id (pk)

关系设置为:

public $belongsToMany = [
    'eventos' => ['JML\Gkb\Models\Evento', 'table' => 'jml_gkb_eventos_etiquetas']
];

public $belongsToMany = [
    'etiquetas' => ['JML\Gkb\Models\Etiqueta', 'table' => 'jml_gkb_eventos_etiquetas']
];

现在,我想要实现的目标:

-get所有具有任何单独标记的事件,而不考虑输入(或)的顺序。

-get所有包含所有标签的事件,不考虑输入顺序(和)。

正如你可以想象的那样,我很喜欢这个,因为我是十月/ Laravel查询构建器的新手(而不是sql)。

到目前为止我做了什么:

if (Session::get('tipo') == 'etiqueta'){
    $pesquisa = preg_split('/\s+/', $temp, -1, PREG_SPLIT_NO_EMPTY);
    if (Session::get('modo') == 0){
        $this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($pesquisa){
            foreach ($pesquisa as $palavra){
                $query->where('etiqueta', 'like', "%$palavra%");
            }
        })->orderBy('id', 'DESC')->paginate(25);
    }
    if (Session::get('modo') == 1){
        $this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($pesquisa){
            foreach ($pesquisa as $palavra){
                $query->orWhere('etiqueta', 'like', "%$palavra%");
            }
        })->orderBy('id', 'DESC')->paginate(25);
    }
}

用户输入由$ temp变量传递,并且它被分割为$ pesquisa数组变量的单词。 'modo'定义用户是否通过AND(0)或OR(1)进行搜索。基于该选择,构建查询以尝试使用$ palavra变量作为$ pesquisa的任何单词来获得结果。

结果:

在modo == 0中,我只能得到一个用户输入标签的事件,如果它有多个单词(第一个单词上不存在的任何字母)没有得到任何结果。

在modo == 1中,它获取所有事件。

在这两种情况下,我都没有得到任何没有任何标签的事件(礼节) - 正确的行为。

我已经尝试过其他一些方法,但没有用...这个看起来最合乎逻辑的尝试......有人能指出我正确的方向吗?

TIA

JL

1 个答案:

答案 0 :(得分:0)

经过一番尝试后,我解决了一半的问题。我想得到的部分" Evento"有任何" Etiqueta"关于用户输入而不是关于它们的顺序最终正常工作。

继续吼叫

    if (Session::get('tipo') == 'etiqueta'){
    $pesquisa = preg_split('/\s+/', $temp, -1, PREG_SPLIT_NO_EMPTY);
    $cadeiapesquisa = implode('|', $pesquisa);
 /***** NOT WORKING YET *****/
    if (Session::get('modo') == 0){
        $this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($pesquisa){
            foreach ($pesquisa as $palavra){
                $query->where('etiqueta', 'like', "%$palavra%");
            }
        })->orderBy('id', 'DESC')->paginate(25);
    }
/****** THIS IS WORKING FINE ! *******/
    if (Session::get('modo') == 1){
        if ( count ($pesquisa) > 0 && !($temp == null)){
            $this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($cadeiapesquisa){

                $query->where('etiqueta', 'regexp', "$cadeiapesquisa");

            })->orderBy('id', 'DESC')->paginate(25);
        } else {
            Evento::paginate(25);
        }
    }
}

第一部分是战斗,但我会到达那里。 :)

TIA

JL

[编辑]

问题已经解决了......到目前为止,我所做的测试所产生的代码片段如下:

    if (Session::get('tipo') == 'etiqueta'){
    $pesquisa = preg_split('/\s+/', $temp, -1, PREG_SPLIT_NO_EMPTY);
    $cadeiapesquisa = implode('|', $pesquisa);
    $contagem = count($pesquisa);
    if (Session::get('modo') == 0){
        if ( strlen($cadeiapesquisa) > 0 ){
            $this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($cadeiapesquisa, $contagem){

                $query->where('etiqueta', 'regexp', "$cadeiapesquisa")->groupBy('evento_id')->having(DB::raw("COUNT('etiqueta_id')"), '>=', $contagem );

            })->paginate(25);
        } else {
            $this['records'] = Evento::paginate(25);
        }
    }
    if (Session::get('modo') == 1){
        if ( strlen($cadeiapesquisa) > 0 ){
            $this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($cadeiapesquisa){

                $query->where('etiqueta', 'regexp', "$cadeiapesquisa");

            })->paginate(25);
        } else {
            $this['records'] = Evento::paginate(25);
        }
    }
}

JL