Laravel,从JSON中删除null Eloquent对象属性

时间:2014-09-05 17:22:52

标签: laravel eloquent

是否有一种优雅的方法可以从Eloquent对象中删除NULL值?我的对象嵌套了关系。这个特定的呼叫可以是1000多行,所以我尝试这个的主要原因是为用户节省带宽,但服务器性能也是一个考虑因素。

我的代码:

$data['locations'] = Location::with('address')->where('user_id', '1')->get();

return Response::json($data);

我尝试使用Mutators,但除非我误认为Mutators没有权力对象密钥,只有价值。

我也试过并且没能像这样使用array_filter:

Any PHP function that will strip properties of an object that are null?

How to remove empty associative array entries

编辑按要求,

{
    "status": "ok",
    "locations": [
        {
            "id": "1",
            "latitude": "12.239107980271",
            "longitude": "109.19479025725",
            "user_time": "",
            "transport": "Bus",
            "title1": "",
            "title2": "",
            "address": {
                "town": "Nha Trang",
                "country": "Vietnam",
                "address": "36-44 Hùng Vương, Lộc Thọ, Nha Trang, Khanh Hoa Province, Vietnam"
            },
            "altitude": {
                "altitude": "10.006237983704"
            },
            "timezone": {
                "offset": "25200"
            },
            "forecast": {
                "icon": "",
                "high_temp": "",
                "low_temp": ""
            }
        },
        {
            "id": "2",

期望回复:

{
    "status": "ok",
    "locations": [
        {
            "id": "1",
            "latitude": "12.239107980271",
            "longitude": "109.19479025725",
            "transport": "Bus",
            "address": {
                "town": "Nha Trang",
                "country": "Vietnam",
                "address": "36-44 Hùng Vương, Lộc Thọ, Nha Trang, Khanh Hoa Province, Vietnam"
            },
            "altitude": {
                "altitude": "10.006237983704"
            },
            "timezone": {
                "offset": "25200"
            }
        },
        {
            "id": "2",

正如你所看到的,我可以简单地遍历整个批次并删除任何键 - 或键的键 - 没有值。我希望Laravel可以提供一种干净利落的方式来做同样的事情。

我应该补充一点,技术上只有纬度和经度是必填字段!

2 个答案:

答案 0 :(得分:3)

3种可能性:

  1. 写一个响应宏来清理你的json数据: http://laravel.com/docs/responses#response-macros
  2. 扩展Response并在那里实施清理例程。有关如何执行此操作的详细信息,请参阅此精彩教程:http://fideloper.com/extend-request-response-laravel
  3. 在模型中实现jsonSerialize方法,当您的模型转换为json并将清理例程放在那里时,将自动调用该方法。您甚至可以更进一步为自己的Collection模型编写自己的Location。根据您的数据结构,这可以使事情变得更容易一些。可以在此处找到一个很好的教程:http://heera.it/extend-laravel-eloquent-collection-object
  4. 我个人更喜欢选项3.)因为数据修改发生在它应该发生的地方 - 在你的模型中。

    但最重要的是,这取决于哪种解决方案最适合您的项目。

答案 1 :(得分:0)

首先制作一个特征并添加自定义验证,然后在需要的每个资源中使用

trait ResourceHelpers
{
    /**
     * Remove null values from Eloquent api resource
     * @param array $data
     * @return array
     */
    public function removeNullValues(array $data)
    {
        $filtered_data = [];
        foreach ($data as $key => $value) {
            $filtered_data[$key] = $this->when($value !== null, $value);
        }

        return $filtered_data;
    }
}

然后在您的资源中使用它

class UserResource extends JsonResource
{

    use ResourceHelpers;

    /**
     * Transform the resource into an array.
     *
     * @param \Illuminate\Http\Request $request
     * @return array
     */
    public function toArray($request)
    {
        return $this->removeNullValues([
            "id" => $this->id,
            "first_name" => $this->first_name,
            "last_name" => $this->last_name,
            "phone" => $this->phone,
            "email" => $this->email,
            "balance" => $this->balance,
            'address' => $this->address,
            'city' => $this->city,
            'state' => $this->state,
            'zip_code' => $this->zip_code,
            'country' => CountryResource::make($this->whenLoaded('country')),
            "joined_at" => $this->created_at,
            "updated_at" => $this->updated_at,
        ]);
    }
}