Laravel,具有联接的全局范围 [英] Laravel, Global scopes with joins

查看:59
本文介绍了Laravel,具有联接的全局范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要定义一个全局过滤器,以便仅在表中获取欲望文件.问题是,需要基于其他关系进行过滤,导致我需要在查询中进行联接.我的问题是,在定义了全局范围之后,该关系具有联接中涉及的所有表的所有行,这会使代码崩溃,因为列不明确.

I need to define a global filter in order to get only the desires files in a table. The problem is that in need to filter based on an other relations cause I need to make a joins in the query. My problem is that after define the global scope the relation has all rows of all the tables involved in the joins this make crash the code because there is ambiguous columns.

我如何只能在过滤后返回产品表?

How i can only return the products table after filtering?

我基于这篇文章中的代码

I based in the code in this post

http://softonsofa.com/laravel如何定义和使用雄辩的全球范围/

laravel帮助 http://laravel.com/docs/4.2/eloquent#global-scopes

the laravel help http://laravel.com/docs/4.2/eloquent#global-scopes

和这个全局过滤-如何在Laravel Eloquent中使用全局范围

我的代码

class PublishedScope implements ScopeInterface {

public function apply(Builder $builder)
{
    $table = $builder->getModel()->getTable();

    $temp  = $builder
      ->select("products.*")
      ->join('products_categories as p_c', 'p_c.product_id', '=', 'products.id')
      ->join('categories as cat', 'p_c.category_id', '=', 'cat.id')
      ->Where(function($query){
          $query->where('cat.id', '!=', '888130');
        }
      );
    $this->addWithDrafts($builder);
}

public function remove(Builder $builder)
{
    $query = $builder->getQuery();
    $column = 'cat.slug';
    $bindingKey = 0;
    foreach ((array) $query->wheres as $key => $where)
    {
        if ($this->isPublishedConstraint($where, $column))
        {
            unset($query->wheres[$key]);
            $query->wheres = array_values($query->wheres);
            $this->removeBinding($query, $bindingKey);
        }

        // Check if where is either NULL or NOT NULL type,
        // if that's the case, don't increment the key
        // since there is no binding for these types
        if ( ! in_array($where['type'], ['Null', 'NotNull'])) $bindingKey++;
    }
}

protected function removeBinding(Builder $query, $key){

    $bindings = $query->getRawBindings()['where'];
    unset($bindings[$key]);
    $query->setBindings($bindings);
}

protected function addWithDrafts(Builder $builder){


    $builder->macro('withDrafts', function(Builder $builder)
    {

        $this->remove($builder);
        return $builder;
    });
  }
}

以及在模型类中

protected static function boot() {
  parent::boot();

  static::addGlobalScope(new PublishedScope);
  }

推荐答案

也许不是最好的解决方案,但在sql中创建子查询可以使其正常工作.

Maybe is not the best solution but ,making a sub query in sql it work properly.

public function apply(Builder $builder){


  $table = $builder->getModel()->getTable();

    $sql = '
        SELECT "products".* 
        FROM (
            SELECT  "products".* 
            FROM    "products" INNER JOIN "products_categories" AS 
                    "p_c" ON "p_c"."product_id" = "products"."id" INNER JOIN 
                    "categories" AS "cat" ON "p_c"."category_id" = "cat"."id" 
             WHERE  (
                    cat.id != 888130
                    )
        )AS products';  

    $builder
      ->select("products.*")
      ->from(DB::raw("($sql) AS products"));
  }
  $this->addWithDrafts($builder);
}

这篇关于Laravel,具有联接的全局范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆