Laravel: find if a pivot table record exists - php

I have two models which are joined by a pivot table, User and Task.
I have a user_id and a task_id.
What is the neatest way to check whether a record exists for this combination of user and task?

You have a couple options depending on your situation.
If you already have a User instance and you want to see if it has a task with a certain id, you can do:
$user = User::find(1);
$hasTask = $user->tasks()->where('id', $taskId)->exists();
You can reverse this if you have the Task instance and want to check for a user:
$task = Task::find(1);
$hasUser = $task->users()->where('id', $userId)->exists();
If you just have the ids, without an instance of each, you could do the following:
$hasPivot = User::where('id', $userId)->whereHas('tasks', function ($q) use ($taskId) {
$q->where('id', $taskId);
})
->exists();

You can also try this, this is working in Laravel 5.7
$user = User::find(1);
$hasTask = $user->tasks->contains($taskId);
But the better way will be
$hasTask = $user->tasks()->where('tasks.id', $taskId)->exists();

may be you search this?
$users = User::has('task')->get();

Easiest to read for me is:
$user->tasks()->exists();

You can use the code below:
$user = User::find(1);
$hasTask = $user->tasks()->where('task_id', $taskId)->exists();

Related

Laravel : How to get all the rows from a table except the first one?

I want to select all the users in my table "User" except the first One cause its the admin,
im using this function index in my controller but it doesn't work .
public function index()
{
// this '!=' for handling the 1 row
$user = User::where('id', '!=', auth()->id())->get();
return view('admin.payroll',compact('user'))->with(['employees' => User::all()]);
}
Better to used here whereNotIn Method
Note: first you find the admin role users and create a static array
$exceptThisUserIds = [1];
$user = User::whereNotIn('id', $exceptThisUserIds)->get();
It's not a good idea to specify the admin user with just id. A better design would be using some sort of a flag like is_admin as a property of your User model.
Still you can use the following code to get the users who have an id greater than 1:
User::where('id', '>', 1)->get()
For getting data skipping the first one you should use skip() method and follow the code like below
public function index()
{
$user = User::orderBy('id','asc')->skip(1)->get();
return view('admin.payroll',compact('user'))->with(['employees' => User::all()]);
}

How to use update() functionality in Laravel?

Inside my store function i have to search a name of a particular person, thus:
$person = DB::select("select p.* from persons p where concat_ws(', ' ,p.family_name,concat_ws(' ',concat_ws(' ',p.first_name,p.middle_name),p.third_name)) like ?", [$request['person_name']]);
If this person exist i have to update the person and this one works:
Person::where('id', $person[0]->id)->update(['status' => 'Active']);
but not this one:
$person[0]->status = 'Active';
$pArray = json_decode(json_encode($person[0]), true);
$per = new Person($pArray);
$per->update();
Since you have already created a new model instance, you would need to call the save() method.
$per = new Person($pArray);
$per->save();
Or, you can use update() to pass data into an existing model. But first, you need to retrieve the model you want to update.
$per = Person::find($pArray['id']);
$per->update($pArray);
Use your search query instead of mine. I think this will help you.
$result = User::where('id', $userId)->first();
$result->name = 'xyz';
$result->update();
For update data in laravel using model you need to pass where condition in it.
Sample example
$flight = App\Flight::find(1);
$flight->name = 'New Flight Name';
$flight->save();
Hope this helps you!

Laravel Eloquent - Select Certain Columns Combine with Eager Loading

How to select certain columns on parents table while querying with eager loading?
$accounts = \App\Account::with('status')->get();
Return
[{"id":1,"username":"kuhn.desiree","email":"quentin.gleason#example.net","last_login":"2009-04-02 23:21:20","created_at":"2017-07-15 19:07:03","updated_at":"2017-07-15 19:07:03","status_id":13,"status":{"id":13,"name":"ab","desc":"Quos quas.","created_at":"2017-07-15 19:07:01","updated_at":"2017-07-15 19:07:01"}}]
I only want username and email on Account table.
Try to use this code:
$accounts = \App\Account::with(['status' => function($q)
{
$q->select('username', 'email');
}])->get();
one way is using select() method
$accounts = \App\Account::with('status')->select('username', 'email','status_id')->get();
If you would like to retrieve a Collection containing the values of a single column, you may use the pluck method.:
accounts = \App\Account::with('status')->pluck('username', 'email');
You want to add a select call:
$accounts = \App\Account::with('status')->select('username', 'email')->get();

(Laravel) only retrieving users that have a relationship

In my site I have users and items. Users can create items. I want to get an array that has all users, where the users which have an item go first and the users which do not have an item go after.
So far I have done this:
$users = User::all();
foreach($users as $user) {
if ($user->item) {
$sortedUsers + $user;
}
// now loop again and add users without relationship
This is pretty inefficient and I'm sure there's a much better way to do it.
You can query on the existence of a relationship
$users = User::has('items')->with('items')->get();
with that syntax you are telling laravel to fetch all users that have a item and to eager load the items;
Edit:
After reading it does not look like you actually want the items just the users that have a item in that case all you need is
$users = User::has('items')->get();
Without seeing the relation of Items to Users I'm not sure if this will work but you can try the following:
$users = Users::select('users.*')->orderBy('items.id')->with('items')->get();
Or it might work with just:
$users = Users::orderBy('items.id')->with('items')->get();
Update
$users = Users::orderBy('items.id')->join('items', 'items.user_id', '=', 'users.id')->get();
you can try
$users = User::with('item')->get();
foreach ($users as $user) {
echo $User->item->name;
}
You can use has() to get users with items and doesntHave() to get users without items:
$withItems = User::has('items')->get();
$withoutItems = User::doesntHave('items')->get();
And then merge() two collections:
$users = $withItems->merge($withoutItems);
You said you want an array, so you can convert result into an array with toArray()
$array = $users->toArray();

Laravel: efficient way to count related models with where clause

I have two models User and Posts
User: id,name
Post: id,title,post,user_id
I want to check if some user has posts with given title.
$user = User::find($userId);
$posts = $user->posts;
$postsWithGivenTitle = $posts->where('title','=',$title);
$postCount = $postsWithGivenTitle->count();
I suppose this above should work but I need to go above this and do it efficiently. So I got this and it's working but still not sure is it the right way to do it.
$user = User::find($userId)->withCount(['posts' => function ($q) use ($title) {
$q->where('title','=',$title);
}])->first();
and then to check the count:
if ($user->posts_count > 0) {
//do something
}
What's confusing me, and looks ugly, is using the methods find() and first() in the same query. So hopefully I'm missing something simple here and overthinking it.
Thanks
As you can see in the docs: https://laravel.com/docs/5.3/eloquent-relationships
You can acheive what you want like this:
$user = User::withCount(['posts' => function($q){....}])->find($id)

Categories