I have user and playerteam model. when a certain team picks up a user for their team. Then it stores in a playerteam model like team_id and player_id.(player_id is a user_id);
now i want to show only those user who are not in playerteam model.
For that i have passed
User::with('playerTeam)->get()
in a blade file. It shows all the users but i want to show only those users whose id is not in playerteam model.
these are the code i have tried
in user model
public function playerTeam()
{
return $this->hasMany(PlayerTeam::class,'player_id');
}
Controller
$data['users'] = User::with('playerTeam')->get();
$data['playerteam'] = PlayerTeam::get();
return view('page',$data);
So, how do i show users that are not in playerteam model.
You may use doesntHave or whereDoesntHave
$data['users'] = User::whereDoesntHave('playerTeam', function ($query) {
$query->where('column', 'value');
})->get();
Or even simpler
$data['users'] = User::doesntHave('playerTeam')->get();
//...
Check docs here
You can use eloquent doesntHave method like this.
User::doesntHave('playerTeam)->get();
It will return all user which don't have a playerTeam relationship.
read docs here laravel doesntHave
$users = User::doesntHave('playerTeam')->get();
use Callback Function
use whereDoesntHave
$data['users'] = User::whereDoesntHave('playerTeam', function ($query) {
$query->where('column', 'value');
})->get();
Refer Following Link
whereDoesntHave
Related
I have a typical pivot table structure like this:
Users
id [...]
Locations
id [...]
User_Location
id | user_id | location_id
I need to get the locations the current authorized user has access to, and then I need to get all the users who also have access to all of those locations.
I tried to figure out an "eloquent" way to do this, but I'm not familiar enough with it. This works, but I'm wondering if it's the best way to do it?
$locations = auth()->user()->locations(); //returns the user_location records
$locationIds = $locations->pluck('location_id');
$locationUsers = new UserLocation();
$userIds = $locationUsers->whereIn('location_id', $locationIds)->groupBy('user_id')->pluck('user_id');
$users = User::withTrashed()
->whereIn('id', $userIds)
->get();
return view('users.index')->with('users', $users);
here's the locations() relationship referenced in the code:
public function locations()
{
return $this->belongsToMany(Location::class, 'user_location')->withPivot('primary');
}
You must create a new method in the Locations model.
public function users()
{
return $this->belongsToMany(User::class, 'user_location');
}
Then your query could look like this.
$locations = auth()->user()->locations()->with('users')->get();
$users = $locations->pluck('users');
If you need to get all users withTrashed then you should modify the first line for this.
$locations = auth()->user()->locations()->with(['users' => function ($user) {
$user->withTrashed();
}])->get();
I want to get all user's online friends, how can I call a custom model function inside the eloquent condition?
this is my code
$friends = $user->friends()->where(function (Builder $query){
$query->where('friend', 'yes');
})
->get();
and this is my function in model
public function getIsOnlineAttribute(): bool
{
// check if the user is online or not
return $this->is_online;
}
I can access is_online after eloquent by foreach, but in my case, I want to check everything in one step ( inside where condition in eloquent). how can I do that???
You can't use conditions for eloquent accessors, in this case you can use (assume 1 is database column value):
$friends = $user->friends()->where('is_online', 1)->get();
or
$friends = $user->friends()->whereIsOnline(1)->get();
or you can create eloquent scope on your model:
public function scopeIsOnline($query) {
$query->where('is_online',1);
}
and you can use this eloquent scope on your controller in this way:
$friends = $user->friends()->isOnline()->get();
this worked for me :)
$friends = $user->friends()
->simplePaginate()
->reject(function ($friend) {
return $friend->is_online === false;
});
I am using laravel eloquent. I have fetched data from two table using eloquent.
I have post table and chat table. For post table I have model Post.php and for chat table I have model Chat.php. Here is the the eloquent relation I have created to fetch chat for individual post for a user.
in Post.php
public function TeamMessage()
{
return $this->hasMany('App\Chat','post_id');
}
And in Chat.php
public function ChatRelation()
{
return $this->belongsTo('App\Post');
}
it is working perfect. But this relation fetch all messages for a specific post. I want to fetch all unread message from chat table. I have a column named unread in chat table.
Now my question is how I can fetch only unread message for a specific post.
While the other answers all work, they either depend on scopes (which are very useful in many circumstances) or on you having already instantiated an instance of $post, which doesn't let you eager load multiple posts with their messages.
The dynamic solution is this, which will let you fetch either 1 or more posts and eager load their messages with subquery:
$posts = Post::with(['TeamMessage' => function ($query) {
$query->where('unread', true); // This part applies to the TeamMessage query
}])->get();
See in documentation
Edit:
If you, however, want to filter the posts, to only show those that have unread messages, you need to use whereHas instead of with:
$posts = Post::whereHas(['TeamMessage' => function ($query) {
$query->where('unread', true); // This part applies to the TeamMessage query
}])->get();
More in the documentation.
You can also chain whereHas(...) with with(...).
For querying relationships, you have to call them as functions instead of properties, like this:
$unreadPosts = $post->TeamMessage()->where('unread', true)->get();
For more information on this you can take a look at the docs.
You need to create a local scope on your model, information on local scopes can be found here: https://laravel.com/docs/5.6/eloquent#local-scopes
public function scopeUnread($query)
{
return $query->where('unread', 1);
}
Then in your controller/view
$unread = $yourmodel->unread()
First I would change your relation names to the name of the entity in lower case:
in Post.php
public function chats()
{
return $this->hasMany('App\Chat','post_id');
}
And in Chat.php
public function post()
{
return $this->belongsTo('App\Post');
}
public function scopeUnread($query)
{
return $query->where('unread', 1);
}
Then you can use
$post->chats()->unread()->get();
Is there a eloquent way to do a left join in Laravel?
We'd like to get all games and fill in the progress for each one if it exists in user_games.
Right now we've written the following solution, however this isn't eloquent at all, which we like it to be.
public function usergames($user_id) {
return DB::table('games')->leftJoin('user_games', function ($join) use ($user_id) {
$join->on('user_games.game_id', '=', 'games.id')->where('user_games.user_id', '=', $user_id); })->get();
}
DB model:
Thanks in advance!
A way to do this without you actually writing a left/inner join is to use the eloquent relationships.
In your case you will have 2 model classes: User and Game
class User extends Model {
public function games() {
return $this->belongsToMany(App\Game::class);
}
}
Now, you can access the user's games like so:
$user = App\User::find($user_id);
$usergames = $user->games; // Illuminate\Support\Collection
If you want to get a list of users with games, then look into eager loading. That would look something like this:
User::with('games')->get();
This way, Eloquent will know to lazy load the relationship meaning it will only run 2 queries. One to grab the users. and one to grab the games associated with the user, and then make them available for you in the 'games' property of the user object.
I have two tables: Users and Images.
So, a user can have some images.
For this relationship I have additional function in model User:
public function images()
{
return $this->hasMany('App\Images', 'idElement', 'id');
}
And in controller I have:
$users = Users::where('id', $id)->with("images")->get();
How can I add additional condition in controller for images table that will be "where images.type = 1"?
Now this tables are connected only by primary keys, but I need to set a new condition yet.
You can filter your images with callback function, try this:
$users = Users::where('id', $id)->with(["images" => function ($query){
$query->where('type', 1);
}])->get();
For something like this, where you want to scope down a subset of images based on their type, you can add another method called something like public function scopedImages() and define it as such:
public function scopedImages() {
return $this->hasMany('App\Images', 'idElement', 'id')->where("images.type", "=", 1);
}
In your controller, you would access this function the same as you would the images() function on User:
$users = Users::where('id', $id)->with(["scopedImages"])->get();
Keep the function images() as well, so if you need to find all images attached to a User, but adding additional functions like this gives you flexibility on what you want to return and when.