How to get all records which meet a Criteria in Laravel Tinker? - laravel

I can get the first user, who is an admin in Laravel's tinker using the following command:
$adminUser = App\User::where('is_admin',true)->first();
How do I get all the users which meet this where criteria?

Just change first() to get().
$adminUser = App\User::where('is_admin',true)->get();
first() is used when you want to retrieve single row or column. where get() is used to retrieve all rows.
just go through the laravel official documentation database query builder section here. It will give you information regarding most of every possible things you can playoff with laravel.

$users = App\User::where("is_admin", true)->get();
The get method returns an Illuminate\Support\Collection containing the results where each result is an instance of the PHP StdClass object. You may access each column's value by accessing the column as a property of the object:
foreach ($users as $user) {
echo $user->name;
}
Src: https://laravel.com/docs/5.6/queries
In case of Tinker, things in Query builder and Eloquent docs will work in Tinker. It exists for the purpose of instantly getting the result without debugging using your real application.

The first() function is used when you want to retrieve single row, whereas the get() function is used to retrieve all matching rows.
$adminUser = App\User::where('is_admin', true)->get();
dd($adminUser);

Related

How dows eager loading work for relations?

I have read the docs I got that if call relation like: users()->author->name it sends another one request in db each time.
But if to call using User()::with("author") it will be loaded eager.
Therefore I try to understand how does it work if I call sometimes the method Auth::user() in controller:
public function controllerMethod(){
Auth::user()->tags();
/// Some logic
Auth::user()->id;
// Some logic
Auth::user()->tags();
}
Does it create a three the same requets in db or two the same and one additional with tags?
If yeas how toad it in global score because I need to get Auth::user() object everywehere in app to show the users fields.
User()::with() is actually an error:
Call to undefined function User()
The correct syntax would be User::with() 🙂
with() tells Laravel's Eloquent which relationship(s) to include when the query is executed. On its own, User::with('author') will not do much. When you use a closure, like ->get() or ->first(), it will execute a subquery, like:
SELECT * FROM authors WHERE user_id IN (...)
That IN (...) clause will change if you're loading a single User via ->first(), or multiple User instances via ->get(), but will make it so ->author doesn't need to call a new Database Query. Each $user->author property will be filled with an Author instance, or null (if that User doesn't have an Author, etc.)
Here's a quick example:
// Executes a single query to load each `User`
// Total Queries: 1
$users = User::get();
// Executes a new query on each loop
// Total Queries: 0 - ∞ (depends on number of loaded `User` instances)
foreach ($users as $user) {
$user->author->name;
}
// Executes a single Query to load each `User`, then a single subquery to load each `Author`
// Total Queries: 2
$users = User::with('author')->get();
foreach ($users as $user) {
$user->author->name;
}
When you call auth()->user(), that returns a single User instance, which has already been loaded from the Database. Calling auth()->user()->author will execute a new Query, since the User returned via auth()->user() didn't include ->with('author').
If you want to Eager Load a relationship on a User that has already been loaded from the Database, you'd call ->load('author'):
// Load the `User` instance from the database for the Authenticated User
$user = auth()->user();
// Executes the subquery `SELECT * FROM authors WHERE user_id = ?`
$user->load('author');
$user->author->name;
// Total Queries: 2
One catch, if you use ->author() (with the ()), it will execute a new Database query, even if you've already called ->load('author') (or ->with('author')):
$user = auth()->user();
$user->load('author'); // Subquery
$user->author()->first()->name; // ANOTHER Subquery
// Total Queries: 3
So the long and short of it is that ->with() will make accessing the relationship as a property, ->author (property) vs ->author()->first() (method), not include another Subquery. If you omit ->with('author'), then both ->author and ->author()->first() will perform a Subquery.

Laravel Eloquent Results Not coming in find all query

I created a Laravel Eloquent Query With all
$result = Model::all()
but when it returns only empty object return as result records are there in the table
when I used
var_dump();die;
instead of
dd();
the result coming perfectly it is something with the
dd();
display

How can I get the data inside my notifications from within my Controller?

I'm trying to get the numbers of records from my notifications, where the candidate_user_id column from inside the data attribute is the same as the UserId (Authenticated User).
After I dd, I was able to get the data from all of the records in the table by using the pluck method (Line 1). I then tried to use the Where clause to get the items that I need
but this just didn't work, it was still returning all of the records in the table.
DashboardController.php:
public function index()
{
$notifications = Notification::all()->pluck('data');
$notifications->where('candidate_user_id', Auth::user()->id);
dd($notifications);
}
Here is a partial screenshot of the data that is being plucked.
How can I get the data from this, in a way like this ->where('candidate_user_id', Auth::user()->id);?
If data was a JSON field on the table you could try to use a where condition to search the JSON using the -> operator:
Notification::where('data->candidate_user_id', Auth::id())->pluck('data');
Assuming you only want this data field and not the rest of the fields, you can call pluck on the builder directly. There isn't much reason to hydrate Model instances with all the fields to then just pluck a single field from them if it is just a table field, so you can ask the database for just the field you want.
The data in the data field is a json string, so you can tell Laravel to automatically cast it as an array using the $casts property on each of the models that is notifiable.
For instance, if you have a User model which uses the trait (ie has use Notifiable), add this:
protected $casts = [
'data' => 'array',
];
If you want to access all notifications for the auth user.
$user = auth()->user();
dd($user->notifications->pluck('data'));
If you really want to do in your question way, here is how.
$notifications = Notification::all()->pluck('data');
$notifications = $notifications->where('candidate_user_id', Auth::user()->id)
->all();
This assumes you that you did not modify the default laravel notifications relationship and database migration setup. If you have modified some of the default ones, you need to provide how you modify it.

How to know what columns are presents in a Eloquent query before to execute it in Laravel 5.5?

Im using Laravel 5.5 and I have and QueryBuilder object (from the "Illuminate/Database/Eloquent/Builder" class).
I want to set an orderBy sentence into my query, but only if this field is present and exists in the QueryBuilder object (as column in the select section sentence).
For example, there is an User model, with the following fields ['id', 'firtsname', 'lastname', 'username','description'].
This is my object:
Use App\User;
$query = User::query();
if ($request->input('sort') != null) {
$model_query->orderBy($request->input('sort'), 'ASC');
}
$users = $query->get();
When I execute it, works fine (if I send you consistent data, of course). But if I set a column what does not exists, it sends and exception. So, the question is, how I can get the columns to retrieve from my $query object? To validate it, and if it's presents, execute the ordening code.
To answer your question, you can get the presence status of a column using Schema::hasColumn()
if (Schema::hasColumn('users', $request->sort)) {
//
}
GOING FURTHER
Now this doesn't seem very efficient, and maybe potentially leak data. Better validating your sort input and accept only proper column names:
$request->validate(['sort' => 'in:column1,column2']);

Use Laravel 5.3 Query Builder to replicate Eloquent ORM data structure for Sub Query

I am trying to replicate the result set that I get when using Eloquent ORM, except with Laravel Query Builder. Basically using this code I can get the packs to appear nested within the products so that when I loop them on the view I can further loop the packs within each products. Seems pretty basic right (see result set below).
$get_posts_for_product = Product::where('active', 1)
->with('packs')
->get()->toArray();
I have tried a few ways using Query Builder to get this to work but it joins the packs inline as I thought it would.
What is the best way to get this same Array structure using Query Builder, I am aware that the result set is a different type of array and that is fine but for my project it must be done using Query Builder at this point.
Thanks.
I would say, that is why you have Eloquent: you don't have to worry about how to have those relationships together.
However incase you really want to achieve the same result I will demo this using two tables users and messages:
1st method:
Retrieve the users and transform it by querying the database for relationships:
$result = DB::table('users')->get()->transform(function ($user){
$user->messages = DB::table('messages')->where('user_id', $user->id)->get();
return $user;
});
Downside: Having many users means a lot of db query on messages table.
Upside: less codes to write
2nd method:
Retrieve both tables using all the ids of user to query the messages:
$users = DB::table('users')->get();
$messages = DB::table('messages')->whereIn('user_id', $users->pluck('id')->toArray())->get();
$result = $users->transform(function ($user) use ($messages){
$user->messages = $messages->where('user_id', $user->id)->values();
return $user;
});
Downside: The need to still transform it.
Upside: Less database trips. i.e two queries only.
3rd method
Looks like the second except that you can group messages by 'user_id' then you do no extra filter when transforming users result:
$user = DB::table('users')->get();
$messages = DB::table('messages')->whereIn('user_id', $user->pluck('id')->toArray())
->get()
->groupBy('user_id');
$result = $user->transform(function ($user) use ($messages){
$user->messages = $messages[$user->id];
return $user;
});
Downside: Same with two.
Upside: no extra filter when transforming users.
Other method
Join on both users and messages when querying then transform the response, or simply use it as it is.
PS: Eloquent uses query builder.
The answer is open for update.

Resources