6

I'm trying to remove created_at and updated_at before returning response to api . I want to removie these field from both Place_Type and Places how can I do that? : I tried : unset(placetypes) but it didn't work

This is my Code:

    public function places()
    {

        $placeType = PlaceType::with('places')->where('id', 1)->get();

        return response()->json(['placeType' => $placeType]);
    }

The request result:

 "placeType": [
        {
            "id": 1,
            "name": "Moriah O'Conner",
            "icon": "https://picsum.photos/200/300",
            "status": 1,
            "created_at": "2019-12-14 18:23:19",
            "updated_at": "2019-12-14 18:23:19",
            "places": [
                {
                    "id": 1,
                    "name": "Linda Leffler",
                    "description": "Alice's shoulder, and it set to work, and very soon came to ME, and told me he was in the air. She did it so VERY remarkable in that; nor did Alice think it would feel very queer to ME.' 'You!' said.",
                    "icon": "https://picsum.photos/200/300",
                    "image_name": "https://picsum.photos/200/300",
                    "rating": 2,
                    "longitude": -53.389979,
                    "latitude": 19.633458,
                    "availability": 1,
                    "status": 1,
                    "place_type_id": 1,
                    "created_at": "2019-12-14 18:23:19",
                    "updated_at": "2019-12-14 18:23:19"
                },
                {
                    "id": 2,
                    "name": "Lauren Cartwright",
                    "description": "I should say \"With what porpoise?\"' 'Don't you mean by that?' said the King. 'I can't remember half of anger, and tried to look at it!' This speech caused a remarkable sensation among the leaves.",
                    "icon": "https://picsum.photos/200/300",
                    "image_name": "https://picsum.photos/200/300",
                    "rating": 1,
                    "longitude": -38.117034,
                    "latitude": -32.248637,
                    "availability": 1,
                    "status": 1,
                    "place_type_id": 1,
                    "created_at": "2019-12-14 18:23:19",
                    "updated_at": "2019-12-14 18:23:19"
                }...,
               }
Mohammad Hosseini
  • 1,649
  • 1
  • 16
  • 31
Fateh Alrabeai
  • 660
  • 3
  • 17
  • 35

6 Answers6

8

Add the fields to the $hidden array:

// Model

protected $hidden = ['created_at', 'updated_at'];
DevK
  • 9,597
  • 2
  • 26
  • 48
  • This must work for any Model query. Please use `protected $hidden = ['created_at', 'updated_at'];` in both `placeType` and `places` model. – Yubaraj Shrestha Dec 15 '19 at 07:19
5

There are different methods you can use.

Method 1 : Fetch only required fields from the database

You can use select() method for retrieving only required fields from db. Hence you can omit the unnecessary fields.

$placeType = PlaceType::with(['places'  => function ($query) {
                    $query->select('id', 'name', 'description', 'icon',
                        'image_name', 'rating', 'longitude', 'latitude',
                        'availability', 'status', 'place_type_id'); //timestamps excluded
                }])
                ->select('id', 'name', 'icon', 'status') //timestamps excluded
                ->where('id', 1)
                ->get();

return response()->json(['placeType' => $placeType]);

This code will output only specified fields both in the parent model (placetype) and child model (places).

If you use these customized select query more than once and writing all field names multiple time is difficult, then you could use model scope like the following.

PlaceType Model

// add all columns from your table
protected $columns = ['id', 'name', 'icon', 'status', 'created_at', 'updated_at'];

public function scopeExclude($query,$value=[]) 
{
    return $query->select( array_diff( $this->columns,(array) $value) );
}

Place Model

// add all columns from your table
protected $columns = ['id', 'name', 'description', 'icon', 'image_name',
                        'rating', 'longitude', 'latitude', 'availability',
                        'status', 'place_type_id', 'created_at', 'updated_at'
                    ];

public function scopeExclude($query,$value=[]) 
{
    return $query->select( array_diff( $this->columns,(array) $value) );
}

Then you could remove unwanted fields like the following

$placeType = PlaceType::with(['places' => function ($query) {
                    $query->exclude(['created_at', 'updated_at']); //exclude fields from Place model
                }])
                ->exclude(['created_at', 'updated_at']) //exclude fields from PlaceType model
                ->where('id', 1)
                ->get();

Courtesy : This SO answer by @Razor

Method 2 : Hide your column from serialization where you need

You can hide your column from serialization using laravel's makeHidden() method. In this method after fetching rows with all fields, you are making the specified fields as hidden. [Please note that the excluded variables won't appear on json but may visible on dump].

//get rows with all fileds (except hidden)
$placeType = PlaceType::with('places')->where('id', 1)->get();
//making timestamps hidden in child model's rows
$placeType->places->makeHidden(['created_at','updated_at']);
//making timestamps hidden in parent model's rows
$placeType->makeHidden(['created_at','updated_at']);

return response()->json($placeType);

Courtesy : This SO answer by @sajed

Method 3 : Using Hidden property

If the timestamps are unnecessary in most of the time in the app, you could use the model's hidden property.

PlaceType Model & Place Model

protected $hidden = ['created_at', 'updated_at'];

Hope this will be helpful.

iamab.in
  • 2,022
  • 3
  • 18
  • 39
2

1) You just need to declare public $timestamps = false; in every model you want to hide it.

2) You can also disable timestamps by removing $table->timestamps() from your migration.

3) Declare protected $hidden = ['created_at', 'updated_at']; in your model.

Mohammad Hosseini
  • 1,649
  • 1
  • 16
  • 31
1

In case you want to remove timestamps from model, as mentioned before, place this in your Model:

public $timestamps = false;

Also create a migration with following code in the up() method and run it:

Schema::table('your_table', function (Blueprint $table) {
    $table->dropTimestamps();
});

You can use $table->timestamps() in your down() method to allow rolling back. or in model

const UPDATED_AT = null;
const CREATED_AT = null;
albus_severus
  • 3,626
  • 1
  • 13
  • 25
1

Assuming that $placeType is array, you can use this recursive function:

function removeTimeStampValues($array) 
{
    if(array_key_exists('created_at', $array) && array_key_exists('updated_at', $array)) {
       unset($array['created_at']);
       unset($array['updated_at']);

    }
    foreach ($array as $key => $value) {
       if(is_array($value)) {
         $array[$key] = recursiveRemoveTimeStampValue($value);
       }
    }

    return $array;
}
pivox
  • 51
  • 3
0

If you don't want these columns, you can do as others said based on the documentation (under "Timestamps" title).

But if you need these column and just don't want them in the json response, you can use resource. See the documentation.

Rouhollah Mazarei
  • 3,969
  • 1
  • 14
  • 20