Laravel : if record not found then search relational model - php

I am trying to find a record in User model , if the record doesn't exists in User model, Then find it in UserCompany model with relation name company in User model.
$companyUser = \App\User::whereHas('company', function ($query) use ($request) {
$query->where('company_email', '=', $request->email);
})->where('email', $request->email)->get();
I am getting empty set there, What am i missing.

You can do like this,
$companyUser = \App\User::where('email', $request->email)
->orWhereHas('company', function ($query) use ($request) {
$query->where('company_email', '=', $request->email);
})->get();

Related

How can I pick single record from one to many relation?

I have one to many relation based two tables users and games and there is also bridge table users_games (linking user_id to games).
I want to fetch a single record from games table based on provided game_id for specific user. I did some research and found whereHas() which is returning all games which are belongs to specific user. But I need to fetch one based on game_id. Can some one kindly let me know how can I fix issue in below script
$GameInfo = User::with('games')->whereHas('games', function ($query) use($request)
{
$query->where('game_id', '=', $request->game_id);
})->find(request()->user()->id);
Is this what you're trying to do?
$GameInfo = $request
->user()
->games()
->where('game_id', $request->game_id)
->first();
try this:
$GameInfo = User::with(['games' => function ($query) use($request)
{
$query->where('game_id', $request->game_id);
}])->whereHas('games', function ($query) use($request)
{
$query->where('game_id', '=', $request->game_id);
})->find(request()->user()->id);
If your relation 'games' is a hasMany() with table 'users_games', You can try this code
$GameInfo = User::with(['games' => function ($query) use($request)
{
$query->where('game_id', $request->game_id);
}])
->where('users.id', <user_id_variable>)
->first();
And the relation 'games' in User Model as
public function games()
{
return $this->hasMany('App\Models\UserGames', 'user_id', 'id');
}

Eloquent relation clarification

Following is my query
$user = User::with(['session' => function ($query) {
$query->select('id','device_id');
$query->where('api_token', '=', '123456');
}])->get();
session: hasMany relation with User.
I am expecting a user with a session having api_token = 123456. Instead I am getting whole users here. I know I am doing something wrong.
I am referring this doc. In the doc it is saying that we can add constraint to the query. But here $query->where('api_token', '=', '123456'); this where is not working.
You are not filtering the User, you are filtering the result of the eager loading of 'session'. Eager loading does not have any effect on the base result set in anyway.
It sounds like you want to filter User by the 'existence' of a relationship in the database.
User::whereHas('session', function ($q) {
$q->where('api_token', '12345');
})->get(); // ->first();
Get all Users that have a Session where 'api_token' == '12345'.
Laravel 5.5 Docs - Eloquent - Relationships - Querying Relationship Existence
Finally I got it worked.
$sessionSelect = function ($query) {
return $query->select( 'user_id', 'device_id');
};
$detailSelect = function ($query) {
return $query->select('user_id', 'dob', 'gender');
};
$sessionWhere = function ($query) use ($key) {
return $query->where('api_token', $key);
};
$users = User::with(['session' => $sessionSelect,'detail'=>$detailSelect])
->whereHas('session', $sessionWhere)
->first();

Laravel whereHas not working as expected

I have a relationship on my User table called 'roles'.
This relationship is:
public function roles()
{
return $this->hasMany('App\RoleUser');
}
I am only trying to fetch users that have a role of 3.
My query is:
User::where('name', $name)
->orWhere('email', $email)
->whereHas('roles', function ($q) {
$q->where('id', 3);
})->get();
This, however, is returning all users no matter what their role. I can confirm that all users have roles and the roles relationship is working.
The fields in the role_user table are 'id', 'user_id'
Looks like this issue was caused by a previous orWhere clause on the query.
Looking at the original query in the question:
User::where('name', $name)
->orWhere('email', $email)
->whereHas('roles', function ($q) {
$q->where('id', 3);
})->get();
This reads as where the name is 'name' and the user has roles and includes a role of 3. The query was also bringing in any results that had an email that matched my provided email but because it was 'orWhere' it ignored the other requirements.

Retrieve models that belongsToMany specific models

I've got a standard many-to-many relationship
class User {
public function roles() {
return $this->belongsToMany('Role');
}
}
class Role {
public function users() {
return $this->belongsToMany('User');
}
}
And it works very well.
But I need to select all the users that has exactly two specific roles.
$roleAdmin = Role::where('name', 'admin')->first();
$roleUser = Role::where('name', 'user')->first();
$users = //which users has BOTH $roleAdmin and $roleUser ??
Is it possible to achieve this using eloquent or I need a raw query?
PS the use-case is stupid, I know, it's just an abstraction of my real problem (that doesn't concern users and roles)
The best solution I found is to get admins and users and then use intersect() helper to get only users who are present both in $users and admins collections:
$users = User::whereHas('roles', function ($q) use($otherRoles) {
$q->where('name', 'user')->whereNotIn('name', $otherRoles);
})->get();
$admins = User::whereHas('roles', function ($q) use($otherRoles) {
$q->where('name', 'admin')->whereNotIn('name', $otherRoles);
})->get();
$result = $admins->intersect($users);
If you want to save some memory, you could pluck() only IDs, intersect() these and only then get users with whereIn().
This is not an eloquent solution(by all means)
$users = \DB::table('users')
->select(\DB::raw("GROUP_CONCAT(roles.name SEPARATOR '-') as `role_names`"), 'users.name')
->join('role_user', 'users.id', '=', 'role_user.user_id')
->join('roles', 'roles.id', '=', 'role_user.role_id')
->groupBy('users.id')
->having('role_names', '=', 'admin-user')
->get();
admin-user can be user-admin, which roles names comes first in the database. Please change table and column names as per your requirement

Using a where condition in multtiple relation eager load in laravel

I have three models
A user created a meeting and other members are invited to that meeting
I need to get the meeting with the detail of the user who created the meeting for the user that is invited to that meeting
So I have an meeting table
Model Meeting
function creator() {
return $this->belongsTo( 'User', 'created_by' );
}
function attendees() {
return $this->hasMany('MeetingAttendees');
}
Model User
function invitedMeetings() {
return $this->hasMany( 'MeetingAttendees' );
}
Model Meeting Attendees
function meeting() {
return $this->belongsTo('Meeting');
}
and finally the code to load the relation. where $user is the User Object
$user->invitedMeetings()
->with(['meeting.creator' => function ($query) use ($status) {
if (!empty($status)) {
$query->where('meetings.status', '=', $status);
}
}])->get();
I need to get only meetings where the $status has a certain value, but the where is adding a query to user table. I cannot seem to add a where in the relation load. How can I achieve this?
You should be able to do this much easier
$user->invitedMeetings()
->with(['meeting', 'meeting.creator'])
->where('status', '=', 'accepted')
->get()
//If you want to do a check on another table
$user->invitedMeetings()
->with(['meeting', 'meeting.creator'])
->where('meeting.status', '=', 'accepted')
->get()
Have a look here to get a better understanding about nesting eloquent relations: Eloquent Nested Relation with Some Constraint
I have figured out the answer for this, so
$user->invitedMeetings()
->with(['meeting.creator' => function ($query) use ($status) {
if (!empty($status)) {
$query->where('meetings.status', '=', $status);
}
}])->get();
should be changed to
$user->invitedMeetings()
->with(['meeting' => function ($query) use ($status) {
$query->where('meetings.status', '=', $status)->with('creator');
}])->get();
This solved my issue

Categories