Laravel 在过滤具有给定值的列时附加 JSON 对象
Laravel appending JSON object when filtering columns with a given value
我正在尝试创建一个搜索栏以允许用户:
(1) 过滤给定值的两个表,
(2) 并在每个 'row'
内附加一个 'status' 列
我做了第一部分如下:
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 结果 returns 很好:
[ { "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 name等于登录用户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 结果 returns 因登录用户而异。
我想最简单的方法是在数据库中添加一个 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()
查询中。由于您需要所有常规列,我们也将 '*'
添加到 select 数组。
编辑:按要求解释:
当我们在 SQL 中执行 select x = y as z ...
时,我们将 x 与 y 进行比较,如果它们相等则 z 设置为 1,否则设置为 0。
所以在 books.b_author = :username as status
中,我们说 "compare the b_author column from the table books with the value :username"。但是 :username
只是我们稍后插入的值的占位符。这就是我们在第二个数组 [Auth::user()->fullname]
中所做的 - 我们将 :username
替换为登录用户的全名值。
这样,您可以直接在查询中进行比较,而不会在 php 之后操作结果数组。
我认为可以通过eloquent模型解决,请看我在项目中使用的解决方案。
为了解决方案的简单性,我只是重写了 toArray()
方法。
例如:
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 ....
}
}
Update-1
根据 5.1.
class User extends Eloquent {
protected $appends = array('status');
public function getStatusAttribute() {
return 'someStatus';
}
}
如果您仍然遇到难以解决的问题,请告诉我。
如果您根本不使用其他成员的帖子,那么您的查询是错误的。应该是这样的:
$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;
}
我正在尝试创建一个搜索栏以允许用户:
(1) 过滤给定值的两个表,
(2) 并在每个 'row'
内附加一个 'status' 列我做了第一部分如下:
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 结果 returns 很好:
[ { "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 name等于登录用户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 结果 returns 因登录用户而异。
我想最简单的方法是在数据库中添加一个 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()
查询中。由于您需要所有常规列,我们也将 '*'
添加到 select 数组。
编辑:按要求解释:
当我们在 SQL 中执行 select x = y as z ...
时,我们将 x 与 y 进行比较,如果它们相等则 z 设置为 1,否则设置为 0。
所以在 books.b_author = :username as status
中,我们说 "compare the b_author column from the table books with the value :username"。但是 :username
只是我们稍后插入的值的占位符。这就是我们在第二个数组 [Auth::user()->fullname]
中所做的 - 我们将 :username
替换为登录用户的全名值。
这样,您可以直接在查询中进行比较,而不会在 php 之后操作结果数组。
我认为可以通过eloquent模型解决,请看我在项目中使用的解决方案。
为了解决方案的简单性,我只是重写了 toArray()
方法。
例如:
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 ....
}
}
Update-1
根据 5.1.
class User extends Eloquent {
protected $appends = array('status');
public function getStatusAttribute() {
return 'someStatus';
}
}
如果您仍然遇到难以解决的问题,请告诉我。
如果您根本不使用其他成员的帖子,那么您的查询是错误的。应该是这样的:
$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;
}