Laravel filter data after with closure - php

I have one quite simple question, Imagine I have Orders model and now I am writing something like that :
Order::where('status', 1)->with('orderer')->get();
Ok. It's simple and returns something like that:
{
id: 1,
price: 200,
status: 1,
income: 21,
orderer_id: 4,
orderer: {
//some orderer fields
}
}
now I don't want to get the whole object, I want to remove income, orderer_id and status properties from data. if I write something like that : get(["id", "price"]) I end up without orderer object (get(["id", "price", "orderer"]) doesn't work too), I couldn't make it work even using select(), so what is the solution? Also I don't want to hide it from everyone, for example admin should know income but user shouldn't, so $hidden field will not work.

You can add select() but make sure select does not take array but comma separated arguments :
$orders = Order::where('status', 1)->with('orderer');
if($user->role == 'admin'){
$orders->select('id','income','status','price');
}
else{
$orders->select('id','status','price');
}
$orders = $orders->get();
Above will first check the current logged in user's role and accordingly will select the columns required.

https://scotch.io/bar-talk/hiding-fields-when-querying-laravel-eloquent-models
In your Order Eloquent model:
protected $hidden = array('hide_this_field', 'and_that_field');
Edit: You want to filter based on role like Admin or User, next time please write that down in your question as well. Well a solution for that is to capture the DB query result, and walk that array, then unset properties of the model if the user is not an admin.
Edit2: I also see a discussion here which might help. Some user suggested using middle ware:
https://laracasts.com/discuss/channels/laravel/hide-eloquent-fields-based-on-user-role-or-any-model

If you are looking for a built in Laravel way to handle this, you could use API Resources: https://laravel.com/docs/5.7/eloquent-resources
php atrisan make:resource OrderResource
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class OrderResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
$current_role = $request->user()->role; //or however you determine admin etc
$out = [
'id' => $this->id,
'price' => $this->price,
'orderer'=> $this->orderer,
];
if($current_role == 'admin'){
$out['income'] = $this->income;
$out['status'] = $this->status;
}
return $out;
}
}
In your Controller action
return OrderResource::collection(Order::where('status', 1)->with('orderer')->get());
If you want something a little more robust, consider https://github.com/spatie/laravel-fractal

Related

Laravel : Get all columns except some of them [duplicate]

When I'm using eloquent, I can use the "where" method then the method 'get' to fill an object containing what I've selected in my database.
I mean:
$users = User::where('gender', 'M')->where('is_active', 1)->get(['pseudo', 'email', 'age', 'created_at'])->toArray();
Here I can choose the columns I want to get like 'pseudo', 'email', etc..
But what I miss in laravel doc is the way to do the contrary.
It could be something like that:
$users = User::where('gender', 'M')->where('is_active', 1)->notGet(['pseudo', 'email', 'age', 'created_at'])->toArray();
Thank you for you futur answer and have a nice day.
If you only need to hide attributes from your model's array or JSON representation, you may use one or both approaches:
Add the
$hidden property to your model
class User extends Model
{
/**
* The attributes that should be hidden for arrays.
*/
protected $hidden = ['password'];
}
Use the
makeHidden
function
$users = $users->makeHidden(['address', 'phone_number']);
See other answers for more details... But sometimes you don't want to load huge data (geospatial, html, logs...) into your application, it will be slow and take more memory. OP asked for an SQL query hence my answer, but most of the time it's more convenient to only hide the data from the JSON response.
AFAIK there is no build in option in SQL to exclude columns explicitly, so Laravel can't do it. But you can try this trick
Update
Another trick is to specify all columns in your model (or use an extra query to get all columns using $this->getTableColumns() from this answer, it can also be cached after each migration to avoid two queries) then add a local scope function
// The below code requires you to define all columns in $columns.
// A better approach is to query the schema of the table and cache it after each
// migration, for more details: https://stackoverflow.com/a/56425794/3192276
protected $columns = ['id','pseudo','email'];
public function scopeExclude($query, $value = [])
{
return $query->select(array_diff($this->columns, (array) $value));
}
Then you can do :
$users = User::where('gender', 'M')
->where('is_active', 1)
->exclude(['pseudo', 'email', 'age', 'created_at'])
->toArray();
using hidden array in model is good, but if you don't want to hide your column all the time and use makeVisible to access them in need, then instead, hide your column from serialization where you need with makeHidden function like this :
$res = Model::where('your query')->get();
$res->makeHidden(['column_one','column_two','column_n']);
return response()->json($res);
I don't know about previous Laravel version, but in 5.4 you can put this line in User model
protected $hidden = ['pseudo', 'email', 'age', 'created_at'];
and then User::find(1); will return all fields except pseudo, email, age, and created_at.
But you still can retrieve those hidden fields by using:
$user = User::find(1);
$email = $user['email']; // or $user->email;
I have looked into the answer by #Razor
But there is Very Conveinent way by skipping $columns property
/**
* Scope a query to only exclude specific Columns.
*
* #author Manojkiran.A <manojkiran10031998#gmail.com>
* #param \Illuminate\Database\Eloquent\Builder $query
* #return \Illuminate\Database\Eloquent\Builder
*/
public function scopeExclude($query, ...$columns)
{
if ($columns !== []) {
if (count($columns) !== count($columns, COUNT_RECURSIVE)) {
$columns = iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveArrayIterator($columns)));
}
return $query->select(array_diff($this->getTableColumns(), $columns));
}
return $query;
}
/**
* Shows All the columns of the Corresponding Table of Model
*
* #author Manojkiran.A <manojkiran10031998#gmail.com>
* If You need to get all the Columns of the Model Table.
* Useful while including the columns in search
* #return array
**/
public function getTableColumns()
{
return \Illuminate\Support\Facades\Cache::rememberForever('MigrMod:'.filemtime(database_path('migrations')).':'.$this->getTable(), function () {
return $this->getConnection()->getSchemaBuilder()->getColumnListing($this->getTable());
});
}
getTableColumns function will get all the columns of the table so you dont need to define the $column property
NOTE: COLUMN NAMES OF TABLE WILL BE CACHED UNTIL CONTENTS OF MIGRATIONS DIRECTORY IS ADDED OR DELETED.
MODIFYING THE CONTENTS OF FILES INSIDE THE MIGRATIONS DIRECTORY WILL
NOT RE-CACHE THE COLUMNS
To clear cache manually you can run php artisan cache:clear
you can use hidden array like this:
class Promotion extends Model
{
protected $table = 'promotion';
protected $hidden = array('id');
}
I have a solution that worked for me, which is slightly different than those already stated.
Solution:
$all_columns = Schema::getColumnListing('TABLE_NAME');
$exclude_columns = ['COLUMN_TO_EXCLUDE_1', 'COLUMN_TO_EXCLUDE_2'];
$get_columns = array_diff($all_columns, $exclude_columns);
return User::select($get_columns)->get();
Reasoning:
For me:
Razor's answer didn't work as I got the following error:
BadMethodCallException with message 'Call to undefined method App/CaseStudy::exclude()'
Then, the remaining answers were attemping to hide the columns within the model. Unfortunately, that would hide them for each method in my class and this isn't something that I wanted.
So, in the end, I modified Razor's solution so that it would work without having to hide any of the columns for each method.
I hope this helps someone! 😊
We get the object eloquent from the model full with all fields, transform it to array and we put it inside of a collection. Than we get all fields except all fields specified in array $fields.
$fields = ['a', 'b', 'c', 'N'];
$object = Model::find($id);
return collect($object->toArray())->except($fields);
More clearly, let's give an example:
// Array of fields you want to remove
$fields_to_remove = ['age', 'birthday', 'address'];
// Get the result of database
$user = User::find($id);
// Transform user object to array
$user = $user->toArray();
// Create a collection with the user inside
$collection = collect($user);
// Get all fields of our collection except these fields we don't want
$result = $collection->except($fields_to_remove);
// Return
return $result;
This example above makes exactly the same thing of the first one, but it's more explained.
you can use makeHidden array like this: (After get() or all())
$users = User::where('gender', 'M')->where('is_active', 1)->get()->makeHidden(['pseudo', 'email', 'age', 'created_at'])->toArray();
You can leverage Illuminate\Support\Facades\Schema::getColumnListing('table_name');
use Illuminate\Support\Facades\Schema;
$users_table_columns = Schema::getColumnListing('users');
$exclude_columns = [
'password',
'token',
'address',
];
$select = array_diff($users_table_columns, (array) $exclude_columns);
$site = User::select($select)
->where('gender', 'M')
->where('is_active', 1)
->first();
I wrapped a slitly changed approach from #manojkiran-a up in a small package, cause I needed it in multiple projects:
https://github.com/laracraft-tech/laravel-useful-traits/#selectallbut
Install via composer:
composer require laracraft-tech/laravel-useful-traits
This is how it is working:
use LaracraftTech\LaravelUsefulTraits\UsefulScopes;
$class = new class extends Model
{
use UsefulScopes;
protected $timestamps = false;
protected $table = 'scope_tests';
};
$class->create([
'foo' => 'foo',
'bar' => 'bar',
'quz' => 'quz',
]);
$class::query()->selectAllBut(['foo'])->first()->toArray();
// return ['bar' => 'bar', 'quz' => 'quz']
Note: Since you can't do a native "select all but x,y,z" in mysql, we need to query (and cache) the existing columns of the table, and then exclude the given columns which should be ignored (not selected) from the existing columns.
Cache: Column names of each table will be cached until contents of migrations directory is added or deleted. Modifying the contents of files inside the migrations directory will not re-cache the columns. Consider to clear the cache whenever you make a new deployment/migration!
You can use unset unset($category->created_at,$category->updated_at);
$fcategory = array();
$kCategory = KCategory::where("enabled", true)->get();
foreach ($kCategory as $category) {
$subkCategory = PostCategory::select("id", "name", "desc")
->where("id_kcategory", $category->id)
->where("enabled", true)
->get();
unset($category->created_at, $category->updated_at);
$fcategory[] = $category;
}

Am I doing eager loading correctly? (Eloquent)

I have a method that needs to pull in information from three related models. I have a solution that works but I'm afraid that I'm still running into the N+1 query problem (also looking for solutions on how I can check if I'm eager loading correctly).
The three models are Challenge, Entrant, User.
Challenge Model contains:
/**
* Retrieves the Entrants object associated to the Challenge
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function entrants()
{
return $this->hasMany('App\Entrant');
}
Entrant Model contains:
/**
* Retrieves the Challenge object associated to the Entrant
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function challenge()
{
return $this->belongsTo('App\Challenge', 'challenge_id');
}
/**
* Retrieves the User object associated to the Entrant
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('App\User', 'user_id');
}
and User model contains:
/**
* Retrieves the Entrants object associated to the User
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function entrants()
{
return $this->hasMany('App\Entrant');
}
The method I am trying to use eager loading looks like this:
/**
* Returns an array of currently running challenges
* with associated entrants and associated users
* #return array
*/
public function liveChallenges()
{
$currentDate = Carbon::now();
$challenges = Challenge::where('end_date', '>', $currentDate)
->with('entrants.user')
->where('start_date', '<', $currentDate)
->where('active', '1')
->get();
$challengesObject = [];
foreach ($challenges as $challenge) {
$entrants = $challenge->entrants->load('user')->sortByDesc('current_total_amount')->all();
$entrantsObject = [];
foreach ($entrants as $entrant) {
$user = $entrant->user;
$entrantsObject[] = [
'entrant' => $entrant,
'user' => $user
];
}
$challengesObject[] = [
'challenge' => $challenge,
'entrants' => $entrantsObject
];
}
return $challengesObject;
}
I feel like I followed what the documentation recommended: https://laravel.com/docs/5.5/eloquent-relationships#eager-loading
but not to sure how to check to make sure I'm not making N+1 queries opposed to just 2. Any tips or suggestions to the code are welcome, along with methods to check that eager loading is working correctly.
Use Laravel Debugbar to check queries your Laravel application is creating for each request.
Your Eloquent query should generate just 3 raw SQL queries and you need to make sure this line doesn't generate N additional queries:
$entrants = $challenge->entrants->load('user')->sortByDesc('current_total_amount')->all()
when you do ->with('entrants.user') it loads both the entrants and the user once you get to ->get(). When you do ->load('user') it runs another query to get the user. but you don't need to do this since you already pulled it when you ran ->with('entrants.user').
If you use ->loadMissing('user') instead of ->load('user') it should prevent the redundant call.
But, if you leverage Collection methods you can get away with just running the 1 query at the beginning where you declared $challenges:
foreach ($challenges as $challenge) {
// at this point, $challenge->entrants is a Collection because you already eager-loaded it
$entrants = $challenge->entrants->sortByDesc('current_total_amount');
// etc...
You don't need to use ->load('user') because $challenge->entrants is already populated with entrants and the related users. so you can just leverage the Collection method ->sortByDesc() to sort the list in php.
also, You don't need to run ->all() because that would convert it into an array of models (you can keep it as a collection of models and still foreach it).

How to filter on Doctrine Entity Object?

So I have a database setup like this.
Phone numbers belong to groupings. And users belong to groupings as well. I'm trying to figure out how to get all users that belong to a grouping but through the entity object instead of just a query if this is possible.
For example I'm aware I could do a query like this...
<?php
/**
* Auto generated by MySQL Workbench Schema Exporter.
* Version 3.0.3 (doctrine2-annotation) on 2017-03-27 04:09:37.
* Goto https://github.com/johmue/mysql-workbench-schema-exporter for more
* information.
*/
namespace Entity;
use Doctrine\ORM\Mapping as ORM;
use Entity\BaseGrouping;
/**
* Entity\Grouping
*
* #ORM\Entity()
*/
class Grouping extends BaseGrouping
{
public function getUsersByPriority(){
global $entityManager;
$users = $entityManager->getRepository('Entity\User')->findBy(array(),array('priority' => 'ASC'));
return $users;
}
}
With a little modification I could add another filter perhaps so that only the correct results pertaining to that group are shown instead of everything. Right now this will result in just every user showing instead of those that should belong to just the group.
What I'm looking for is something kind of like this...
$results = $entityManager->getRepository('entity\Phonenumber')->findBy(array('number' => '+'.$numberCalled));
if(count($results)<=0 || count($results)>1){
sendEmail('Error Occured', 'There was duplicate phone numbers in the database, used fallbacknumber<br/><br/>'.print_r($_REQUEST,true),"joe#poolserviceusa.com");
return $fallbacknumber;
}else{
$phonenumber = $results[0];
$group = $phonenumber->getGrouping(); //#JA - Returns the group object and stores it to variable group in scope
}
//Get list of all users in the group
$users = $group->getUsersByPriority(); //#JA - Returns all users associated with the group
//Find the first active and not busy user
foreach($users as $user){
echo '<test>'.$user->getUserName().'<test>';
}
Since I mapped correctly all the doctrine classes I'm able to just say $phonenumber->getGroupings(); and it returns me only the groupings that belong to that phonenumber which is perfect!
What I need now however is all the users that belong to that particular group?
Easy enough if we do $group->getUsers(); The problem here is I need the users sorted by priority and there is no sorting when I use these default methods.
How do I get all the users of just the group while sorting by priority?
I think I found the answer but I don't know if this is the best answer or not. I modified the function getUsersByPriority to this.
public function getUsersByPriority(){
global $entityManager;
$grouping_id = $this->getId();
$users = $entityManager->getRepository('Entity\User')->findBy(array('grouping_id' => $grouping_id),array('priority' => 'ASC'));
//#JA - Get reference to the users of just this grouping.
$users = $this->users;
return $users;
}
I didn't realize I could use $this->getId(); to get reference to the current instance in this case.

Laravel 4. Return database table as JSON

Im really new to Laravel. I have manage to set up a database via the migration functionality, and now i want to renturn a table from the database as json. What im working on is kind of a rest-api-thingy. Nothing too fancy.
In my router i have a route going to /api/cases wich inits the controller for the cases. From that controller i basically just want to return a table from my database as JSON.
Router:
Route::resource('/api/cases', 'CasesController');
Controller:
class CasesController extends \BaseController {
public function index()
{
//return db table as json here
}
}
Model:
class Case extends \Eloquent {
protected $fillable = [];
}
And my database looks like this:
I have only one table, named "cases". That one has attributes like "id", "name", "title".
How would i now return that rest-like as json?
You can simply call the toJSON() method:
Case::all()->toJson();
I assume you have your Case model tested and working properly. Once that's done, you can query for all the objects in this table, convert the result to an array, and encode it as JSON.
public function index()
{
return Response::json(Case::all()->toArray());
}
I don't believe it is the job of the ORM to worry about presentation logic, and that is what JSON is. You'll aways need to cast data to various types as well as hide things and sometimes create a buffer zone to rename things safely.
You can do all of that with Fractal which I built for exactly this reason.
<?php namespace App\Transformer;
use Acme\Model\Book;
use League\Fractal\TransformerAbstract;
class BookTransformer extends TransformerAbstract
{
/**
* List of resources possible to include
*
* #var array
*/
protected $availableIncludes = [
'author'
];
/**
* Turn this item object into a generic array
*
* #return array
*/
public function transform(Book $book)
{
return [
'id' => (int) $book->id,
'title' => $book->title,
'year' => (int) $book->yr,
'links' => [
[
'rel' => 'self',
'uri' => '/books/'.$book->id,
]
],
];
}
/**
* Include Author
*
* #return League\Fractal\ItemResource
*/
public function includeAuthor(Book $book)
{
$author = $book->author;
return $this->item($author, new AuthorTransformer);
}
}
Embedding (including) stuff might be a bit more than you need right now, but it can be very handy too.
I often give talks about APIs and the dangers of trying to expose database schema directly. Unless you app is on an internal network, and only your app looks at this data, and your app will never going to change at all then interacting directly with the table is a very bad idea.
Here is my talk, which uses Laravel as an example a few times.

How to exclude certains columns while using eloquent

When I'm using eloquent, I can use the "where" method then the method 'get' to fill an object containing what I've selected in my database.
I mean:
$users = User::where('gender', 'M')->where('is_active', 1)->get(['pseudo', 'email', 'age', 'created_at'])->toArray();
Here I can choose the columns I want to get like 'pseudo', 'email', etc..
But what I miss in laravel doc is the way to do the contrary.
It could be something like that:
$users = User::where('gender', 'M')->where('is_active', 1)->notGet(['pseudo', 'email', 'age', 'created_at'])->toArray();
Thank you for you futur answer and have a nice day.
If you only need to hide attributes from your model's array or JSON representation, you may use one or both approaches:
Add the
$hidden property to your model
class User extends Model
{
/**
* The attributes that should be hidden for arrays.
*/
protected $hidden = ['password'];
}
Use the
makeHidden
function
$users = $users->makeHidden(['address', 'phone_number']);
See other answers for more details... But sometimes you don't want to load huge data (geospatial, html, logs...) into your application, it will be slow and take more memory. OP asked for an SQL query hence my answer, but most of the time it's more convenient to only hide the data from the JSON response.
AFAIK there is no build in option in SQL to exclude columns explicitly, so Laravel can't do it. But you can try this trick
Update
Another trick is to specify all columns in your model (or use an extra query to get all columns using $this->getTableColumns() from this answer, it can also be cached after each migration to avoid two queries) then add a local scope function
// The below code requires you to define all columns in $columns.
// A better approach is to query the schema of the table and cache it after each
// migration, for more details: https://stackoverflow.com/a/56425794/3192276
protected $columns = ['id','pseudo','email'];
public function scopeExclude($query, $value = [])
{
return $query->select(array_diff($this->columns, (array) $value));
}
Then you can do :
$users = User::where('gender', 'M')
->where('is_active', 1)
->exclude(['pseudo', 'email', 'age', 'created_at'])
->toArray();
using hidden array in model is good, but if you don't want to hide your column all the time and use makeVisible to access them in need, then instead, hide your column from serialization where you need with makeHidden function like this :
$res = Model::where('your query')->get();
$res->makeHidden(['column_one','column_two','column_n']);
return response()->json($res);
I don't know about previous Laravel version, but in 5.4 you can put this line in User model
protected $hidden = ['pseudo', 'email', 'age', 'created_at'];
and then User::find(1); will return all fields except pseudo, email, age, and created_at.
But you still can retrieve those hidden fields by using:
$user = User::find(1);
$email = $user['email']; // or $user->email;
I have looked into the answer by #Razor
But there is Very Conveinent way by skipping $columns property
/**
* Scope a query to only exclude specific Columns.
*
* #author Manojkiran.A <manojkiran10031998#gmail.com>
* #param \Illuminate\Database\Eloquent\Builder $query
* #return \Illuminate\Database\Eloquent\Builder
*/
public function scopeExclude($query, ...$columns)
{
if ($columns !== []) {
if (count($columns) !== count($columns, COUNT_RECURSIVE)) {
$columns = iterator_to_array(new \RecursiveIteratorIterator(new \RecursiveArrayIterator($columns)));
}
return $query->select(array_diff($this->getTableColumns(), $columns));
}
return $query;
}
/**
* Shows All the columns of the Corresponding Table of Model
*
* #author Manojkiran.A <manojkiran10031998#gmail.com>
* If You need to get all the Columns of the Model Table.
* Useful while including the columns in search
* #return array
**/
public function getTableColumns()
{
return \Illuminate\Support\Facades\Cache::rememberForever('MigrMod:'.filemtime(database_path('migrations')).':'.$this->getTable(), function () {
return $this->getConnection()->getSchemaBuilder()->getColumnListing($this->getTable());
});
}
getTableColumns function will get all the columns of the table so you dont need to define the $column property
NOTE: COLUMN NAMES OF TABLE WILL BE CACHED UNTIL CONTENTS OF MIGRATIONS DIRECTORY IS ADDED OR DELETED.
MODIFYING THE CONTENTS OF FILES INSIDE THE MIGRATIONS DIRECTORY WILL
NOT RE-CACHE THE COLUMNS
To clear cache manually you can run php artisan cache:clear
you can use hidden array like this:
class Promotion extends Model
{
protected $table = 'promotion';
protected $hidden = array('id');
}
I have a solution that worked for me, which is slightly different than those already stated.
Solution:
$all_columns = Schema::getColumnListing('TABLE_NAME');
$exclude_columns = ['COLUMN_TO_EXCLUDE_1', 'COLUMN_TO_EXCLUDE_2'];
$get_columns = array_diff($all_columns, $exclude_columns);
return User::select($get_columns)->get();
Reasoning:
For me:
Razor's answer didn't work as I got the following error:
BadMethodCallException with message 'Call to undefined method App/CaseStudy::exclude()'
Then, the remaining answers were attemping to hide the columns within the model. Unfortunately, that would hide them for each method in my class and this isn't something that I wanted.
So, in the end, I modified Razor's solution so that it would work without having to hide any of the columns for each method.
I hope this helps someone! 😊
We get the object eloquent from the model full with all fields, transform it to array and we put it inside of a collection. Than we get all fields except all fields specified in array $fields.
$fields = ['a', 'b', 'c', 'N'];
$object = Model::find($id);
return collect($object->toArray())->except($fields);
More clearly, let's give an example:
// Array of fields you want to remove
$fields_to_remove = ['age', 'birthday', 'address'];
// Get the result of database
$user = User::find($id);
// Transform user object to array
$user = $user->toArray();
// Create a collection with the user inside
$collection = collect($user);
// Get all fields of our collection except these fields we don't want
$result = $collection->except($fields_to_remove);
// Return
return $result;
This example above makes exactly the same thing of the first one, but it's more explained.
you can use makeHidden array like this: (After get() or all())
$users = User::where('gender', 'M')->where('is_active', 1)->get()->makeHidden(['pseudo', 'email', 'age', 'created_at'])->toArray();
You can leverage Illuminate\Support\Facades\Schema::getColumnListing('table_name');
use Illuminate\Support\Facades\Schema;
$users_table_columns = Schema::getColumnListing('users');
$exclude_columns = [
'password',
'token',
'address',
];
$select = array_diff($users_table_columns, (array) $exclude_columns);
$site = User::select($select)
->where('gender', 'M')
->where('is_active', 1)
->first();
I wrapped a slitly changed approach from #manojkiran-a up in a small package, cause I needed it in multiple projects:
https://github.com/laracraft-tech/laravel-useful-traits/#selectallbut
Install via composer:
composer require laracraft-tech/laravel-useful-traits
This is how it is working:
use LaracraftTech\LaravelUsefulTraits\UsefulScopes;
$class = new class extends Model
{
use UsefulScopes;
protected $timestamps = false;
protected $table = 'scope_tests';
};
$class->create([
'foo' => 'foo',
'bar' => 'bar',
'quz' => 'quz',
]);
$class::query()->selectAllBut(['foo'])->first()->toArray();
// return ['bar' => 'bar', 'quz' => 'quz']
Note: Since you can't do a native "select all but x,y,z" in mysql, we need to query (and cache) the existing columns of the table, and then exclude the given columns which should be ignored (not selected) from the existing columns.
Cache: Column names of each table will be cached until contents of migrations directory is added or deleted. Modifying the contents of files inside the migrations directory will not re-cache the columns. Consider to clear the cache whenever you make a new deployment/migration!
You can use unset unset($category->created_at,$category->updated_at);
$fcategory = array();
$kCategory = KCategory::where("enabled", true)->get();
foreach ($kCategory as $category) {
$subkCategory = PostCategory::select("id", "name", "desc")
->where("id_kcategory", $category->id)
->where("enabled", true)
->get();
unset($category->created_at, $category->updated_at);
$fcategory[] = $category;
}

Categories