繁体   English   中英

Laravel在过滤具有给定值的列时附加JSON对象

[英]Laravel appending JSON object when filtering columns with a given value

我正在尝试创建一个搜索栏,以允许用户:

(1)过滤具有给定值的两个表,

(2),并在每个“行”内附加一个“状态”列

我做了第一部分,如下所示:

public function getFilterBooks($input)
{
    $books = DB::table('books')
    ->join('categories', 'books.cat_id', '=', 'categories.id')
    ->where('b_name', 'LIKE', '%' . $input . '%')
    ->orWhere('b_author', 'LIKE', '%' . $input . '%')
    ->orWhere('cat_name', 'LIKE', '%' . $input . '%')
    ->get();
 }

return Response::json($books);

JSON结果返回正常:

[ { "id" : 1,
    "b_name" : "foo Name",
    "b_author" : "bar author",
    "cat_name" : "foobar cat",
  },
  { "id" : 2,
    "b_name" : "foo Name2",
    "b_author" : "bar author2",
    "cat_name" : "foobar cat2",
  }
 ]

但是,我想在此处添加一些逻辑属性,例如,当b_author名称等于登录用户fullname时 ,然后将状态显示为true ,否则显示false

这样的事情:(显然这是行不通的)

if($books.b_author == Auth::user()->fullname){
  //set status as 'true'
}

添加应显示以下内容:

[ { "id" : 1,
    "b_name" : "foo Name",
    "b_author" : "bar author",
    "cat_name" : "foobar cat",
    "status" : true
  },
  { "id" : 2,
    "b_name" : "foo Name2",
    "b_author" : "bar author2",
    "cat_name" : "foobar cat2",
    "status" : false
  }
 ]

因此,JSON结果根据登录用户的不同而返回。

如果您根本不使用其他成员的帖子,则您的查询是错误的。 应该是这样的:

$books = DB::table('books')
    ->join('categories', 'books.cat_id', '=', 'categories.id')
    ->where(function ($clause) {
        $clause->where('b_name', 'LIKE', '%' . $input . '%')
            ->orWhere('cat_name', 'LIKE', '%' . $input . '%')
    })
    ->where('b_author', Auth::id())
    ->get();

如果确实要使用它们,请将以下两段代码添加到模型中:

protected $appends = [ 'status' ];

--

public function getStatusAttribute()
{
    return $this->b_author == Auth::user()->fullname;
}

我认为这可以通过雄辩的模型解决,请看一下我在项目中使用的解决方案。

为了简化解决方案,我只重写了toArray()方法。

对于elxample:

class Example extends \Eloquent {
    //...
    public function toArray(){
        $array = parent::toArray();
        $array['status'] = ($array['b_author'] == Auth::user()->fullname)?true:false; 
        //just updating to required attribute result
        return $array;
    }
}

每当我使用以下方式调用此模型时:

Example::all()->toArray()

这将自动将元素添加到数组的所有元素。

更新资料

处理模型中逻辑属性的另一种方法:

为了强制将属性返回到数组中,请将其作为键添加到$ attributes数组中。

class User extends Eloquent {
    protected $attributes = array(
        'status' => '',
    );

    public function getStatusCode()
    {
        return ....
    }
}

更新1

按照5.1。

class User extends Eloquent {
 protected $appends = array('status');

    public function getStatusAttribute() {
      return 'someStatus';
   }
}

如果您仍然遇到难以解决的问题,请通知我。

我想最简单的方法是在数据库中执行此操作并添加一个select子句,如下所示:

public function getFilterBooks($input)
{
    $books = DB::table('books')
    ->join('categories', 'books.cat_id', '=', 'categories.id')
    ->select(
        ['*', DB::raw('books.b_author = :username as status')], 
        [Auth::user()->fullname]
    )
    ->where('b_name', 'LIKE', '%' . $input . '%')
    ->orWhere('b_author', 'LIKE', '%' . $input . '%')
    ->orWhere('cat_name', 'LIKE', '%' . $input . '%')
    ->get();
}

return Response::json($books);

Auth::user()->fullname放在一个单独的数组中的原因是,即使我们在DB::raw()查询中使用了它,我们也希望对其进行正确的转义。 并且由于您需要所有常规列,因此我们也将'*'添加到选择数组中。

编辑:根据要求的说明:

当在SQL中select x = y as z ...时,我们将x与y进行比较,如果相等,则将z设置为1,否则将其设置为0。

因此,在books.b_author = :username as status ,我们要说“将表簿中的b_author列与值:username进行比较”。 但是:username只是一个占位符,它将在以后插入一个值。 这就是我们在第二个数组[Auth::user()->fullname]所做的工作-我们将:username替换为登录用户的全名值。

这样,您可以直接在查询中进行比较,而后无需在php中麻烦就可以操作结果数组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM