Laravel Eloquent:如何过滤多个和/或标准单表

时间:2015-07-13 06:42:08

标签: php database laravel filter eloquent

我正在制作一个与房地产相关的应用程序,我一直很难弄清楚如何设置查询,以便它返回“只在选定区域内的公寓或双工”我想用户是能够在城市的多个选定象限中找到多种类型的财产。

我有一个带有“type”列的数据库,它可以是“Apartment”,“House”,“Duplex”,“Mobile”

在另一栏中,我的quadrant_main值为:“NW”,“SW”,“NE”,“SE”。

我的代码只在选择了一个象限时有效,但当我选择多个象限时,我似乎得到的结果包括来自第二或第三或第四象限的所有属性类型,而不仅仅是“公寓”和“双工” “或用户选择的任何类型......任何帮助将不胜感激! thx提前。

我的控制器功能如下所示:

public function quadrants()
{
    $input = \Request::all();
    $currentPage = null;
    $column = "price";
    $order = "desc";

    //
    //  Looks like the input is like 0 => { key: value } ...
    //  (an Array of key/value pairs)

    $q = Listing::where('status','=','Active')->where(function($query) {
        $input = \Request::all();
        $currentPage = null;
        $typeCount = 0;
        $quadrantCount = 0;

        foreach( $input as $index => $object ) {

            $tempObj = json_decode($object);
            $key = key((array)$tempObj);
            $val = current((array)$tempObj);

            if ( $key == "type" ) {
                if ( $typeCount > 0 ) {
                    $query->orWhere('type', '=', $val );
                }
                else {
                    $query->where('type', '=', $val );
                    $typeCount++;
                }
            }
            if ( $key == "quadrant_main" ) {
                if ( $quadrantCount > 0 ) {
                    $query->orWhere('quadrant_main', '=', $val );
                }
                else {
                    $query->where('quadrant_main', '=', $val );
                    $quadrantCount++;
                }
            }
            // else {
            //  $query->orWhere($key,$val);
            // }
        }

        if( $currentPage ) {
            //Force Current Page to Page of Val
            Paginator::currentPageResolver(function() use ($currentPage) {
                return $currentPage;
            });
        }
    });

    $listings = $q->paginate(10);

    return $listings;

1 个答案:

答案 0 :(得分:1)

看看你的问题,它有点令人困惑,并没有给予肯定回答。您遇到麻烦的可能原因可能是数据库中的数据不良,或者可能是用户输入错误。

  

免责声明:请注意,我的答案很可能对你不起作用。   在这种情况下,请提供更多信息,我们将工作   进行。

有一件事我认为你忽略了,因此你得到了糟糕的结果。首先让我假设一些事情。

我认为示例用户输入应如下所示:

array(
    0: '{type: Apartment}',
    1: '{type: Duplex}',
    2: '{quadrant_main: NW}',
    3: '{quadrant_main: SW}',
)

用户的意思是给我任何属于NW或SW地区的公寓或复式。

因此,在循环结束后,最终的SQL语句应该是这样的:

  

哦,当我们处于SQL主题时,您也可以记录实际情况   在laravel中生成SQL查询,以便您可以实际查看是什么   最终的SQL生成。如果你可以在这里发布,它会有所帮助   许多。 Look here.

select * from listings where status = 'Active' and (type = 'Apartment' or type = 'Duplex' and quadrant_main = 'NW' or quadrant_main = 'SW');

这个查询实际产生的是:

Select any listing which is active and:
1. Type is an apartment, or,
2. Type is a duplex, or,
3. Quadrant is SW, and,
4. Quadrant is NW

假设您有这样的数据库:

id|type|quadrant_main
=====================
1|Apartment|NW
2|Apartment|SW
3|Apartment|NE
4|Apartment|SE
5|Duplex|NW
6|Duplex|SW
7|Duplex|NE
8|Duplex|SE
9|House|NW
10|House|SW
11|House|NE
12|House|SE

您只会在结果集中收到1, and 5。此结果集显然是错误的,而且它取决于NW,因为这是and条件。

正确的SQL查询是:

select * from listings where status = 'Active' and (type = 'Apartment' or type = 'Duplex') and (quadrant_main = 'NW' or quadrant_main = 'SW');

因此,构建您的L5应用程序,以便它生成这种SQL查询。而不是试图在一个循环中塞满所有东西,有两个循环。一个循环应该只处理type而另一个循环应该只处理quadrant_main。这样,您就可以在正确的位置获得必要的and条件。

作为旁注:

  1. 永远不要直接使用用户输入。一定要先消毒它。
  2. 将所有逻辑放在控制器中并不是最佳做法。使用存储库模式。 See here.
  3. 多个where子句通常通过Criteria应用。检查上面链接的存储库模式。
  4. 你的代码逻辑非常复杂,完全不必要。而不是发送JSON对象,只需发送复选框的状态。不要试图通过循环来概括功能。而是逐个处理所有复选框,即" Apartments"选中,如果是,请将其添加到您的条款,如果没有,请不要添加。