I have this tables
usercontract
user
invite
Invite contain the invitations to participate in a contract and they are send by email. I want to use the email as id in order to get all the contracts a user as been invited to participate to.
And I need to do it as a relationship on my User model, so I can use the logged user email as filter.
This is the relationship I have defined but is using the id of the user to match with the foreing_key (usercontract) on the invite table. I don't understand very well why.
public function nonAcceptedContracts()
{
return $this->belongsToMany(UserContract::class, 'invite', 'email', 'usercontract');
}
I need it as a relationship because I want to call it on my repository, like this.
public function showRelated(User $user)
{
$parentUser = $user->parentUser;
$usercontract = UserContract
::with(['topics', 'contracttax', 'contractproperty', 'persons', 'contractwarranty', 'contractencumbrance', 'users', 'contracts', 'tags'])
->whereHas('users', function ($query) use ($user, $parentUser) {
$user->loadMissing('nonAcceptedContracts');
dd($user->nonAcceptedContracts);
$query->where('id', $user->getAuthIdentifier());
if ($parentUser) {
$query->orWhere('parent', $parentUser->id);
}
if ($user->siblingUsers()->count() > 0) { // get contracts of the sibling-users of the user
$query->orWhereIn('id', $user->siblingUsers()->pluck('id'));
}
if ($user->subUsers->count() > 0) { // get contracts of the users sub-users
$query->orWhereIn('id', $user->subUsers->pluck('id'));
}
return $query;
})->orderBy('created_at', 'desc')->get();
}
I guess my question is how to set a relationship in order to get the usercontracts for that user (the object) using his email as a key to get the usercontract id (usercontract) on the invite table.
SELECT * FROM `usercontract` WHERE usercontract.id IN (SELECT invite.id FROM invite WHERE `invite`.`email` = 'someemail#gmail.com')
public function nonAcceptedContracts()
{
return $this->belongsToMany(UserContract::class, 'invite', 'email', 'usercontract', 'email')->where('status', 'pending');
}
That relationship uses my "invite" table as pivot using the "email" and "usercontract" has keys and filtering the results with the "email" of the "user" table.
Related
for my app I made it so an user can favorite venues, this relationship between venues and user is many to many, problem is I don't know how to get favorite_venues paginated.
Right now what I'm doing is getting user with favorite_venues but that doesn't seem right to me, is there a way to get favorite venues paginated directly without having to get the user.
What I'm currently doing:
public function getFavorites($request)
{
$user = User::with(['favoritevenues','favoritevenues.category'])->findOrFail(1);
return $user;;
}
I set relationships like this:
User Model
public function favoritevenues()
{
return $this->belongsToMany('App\Models\Venue', 'favorite_venues', 'user_id', 'venue_id')->withTimeStamps();
}
Venue Model
public function favorites()
{
return $this->belongsToMany('App\Models\User', 'favorites', 'venue_id', 'user_id')->withTimeStamps();
}
Thanks in advance
you can do:
Venue::whereHas('favorites', function ($q) {
return $q->where('id', 1);
})->paginate(5);
This will get and paginate all the venues which are the favourites of user with id 1
I have the following tables. users, user_details and client_teams. Each user has one details and each user can have many teams. schema for users:
id, name, email,parent_user_id
user_details:
id, user_id, client_team_id
client_teams:
id, user_id, team_name,status
In user_model i have the following relations:
public function userDetails(){
return $this->belongsTo('App\Models\UserDetails','id','user_id');
}
public function clientTeamList(){
return $this->hasMany('App\Models\ClientTeams','user_id','id');
}
In user_details model i have the following relation:
public function clientMemberTeam(){
return $this->belongsTo('App\Models\ClientTeams','client_team_id');
}
I want to be show the list of users who have a specific team ID and created by a specific user. The query that i am using is this:
$userCollections=Users::where([
['users.status','!=','DELETE'],
['users.parent_user_id',$clientId],
['users.id','!=',$loginUser->id]
])
->with([
'userDetails'=>function($query) {
$query->where('client_team_id',1);
}
]);
This is giving me all records for this user, Whereas i want to match by client_team_id and user_id
You need to use whereHas and orWhereHas methods to put "where" conditions on your has queries.
Please look into https://laravel.com/docs/8.x/eloquent-relationships
$userCollections = Users::where([['users.status', '!=', 'DELETE'],
['users.parent_user_id', $clientId],['users.id', '!=', $loginUser->id]
])
->whereHas('userDetails' => function ($query) {
$query->where('client_team_id', 1);
})->get();
I am trying to get my Yajra Datatable working correctly but struggling.
Basically I want to get all clients appointments in which the client belongs to the logged in user. I then want to access the Client name and then the appointment data. I have used the following to get the appointment data
$user = User::find(Auth::user()->id);
$data = $user->clients()->with('appointments')->get()->pluck('appointments')->flatten();
return Datatables::of($data)
->make(true);
This allows me to show a row for each appointment that exists for the user-owned clients appointments. But how can I also access the clients name from this?
I have tried many different ways but if I use something like
$data = $user->clients()->with('appointments')->get();
I can access all of the data I need but it shows the existing clients in each row, not all appointments owned by the clients.
My setup is
User Model
public function clients(){
return $this->hasMany(Client::class);
}
public function appointments()
{
return $this->hasManyThrough(Appointment::class, Client::class);
}
Client Model
public function appointments(){
return $this->hasMany(Appointment::class);
}
public function users(){
return $this->belongsTo(User::class);
}
Appointment Model
public function client(){
return $this->belongsTo(Client::class);
}
Thank you
You might be looking for whereHas:
$appointments = Appointment::with('client')
->whereHas('client.users', function ($query) use ($user) {
$query->where('users.id', $user->id)
})
->get();
This translates to: "Give me all the appointments that belong to clients of a specific user".
Just a suggestion, it might be wise (not required at all) to alter your database structure to something more flexible. What if you for instance keep track in you appointment which user is present?
appointments
- user_id
- client_id
This would make your query a bit simpler
// In User
public function appointments()
{
return $this->hasMany(Appointment::class);
}
$user->appointments()->with('client')->get();
You could go even further by making the relation between User and Appointment, Client and Appointment many to many so you could have appointments with more than one user and/or client.
I have 3 Tables:
Customers
id
name
Sales
customer_id
sale_date
Contacts
customer_id
contact_date
There aren't any update operations in the contacts table. Each process opens a new record in the contacts table. So, a user can have more than one records in the contacts table.
Here are my relations in models:
Customer
public function contacts()
{
return $this->hasMany(Contact::class);
}
public function sales()
{
return $this->hasMany(Sale::class);
}
Contact
public function customer()
{
return $this->belongsTo('App\Customer', 'customer_id');
}
Sale
public function customer()
{
return $this->belongsTo('App\Customer');
}
I would like to have the latest record of the contacts table and make it join with the other related tables.
Here is the query which I have tried:
$record = Contact::groupBy('customer_id')
->select(DB::raw('max(id)'));
$result = Customer::query();
$result->where('is_active', 'YES');
$result->with('sales');
$result->whereHas('contacts', function ($q) use($record){
return $q->whereIn('id', $record)->where('result', 'UNCALLED');
});
return $result->get();
In the blade file, I get some result in foreach loops. However, I am unable to get the related data from the sales and contacts table.
#foreach($result as $item)
#foreach($item->sales as $sale) // Has no output and gives error: Invalid argument supplied for foreach()
#foreach($item->contacts as $contact) // Has no output and gives error: Invalid argument supplied for foreach()
Can anyone help me how to display the sale and contact date? Or any idea for how to improve this code quality?
If you want the latest record of the contacts you can declare another relationship on the Customer model, e.g.:
public function latest_contact()
{
return $this->hasOne(Contact::class)->latest('contact_date');
}
BTW you can always declare one or more hasOne additional relationship if you have a hasMany in place the foreign key used is the same.
In this way you can retrieve latest_contact eager loaded with your Customer model:
$customer = Customer::with('latest_contact')->find($id);
Or use this relationship in your queries, something like that:
$customers = Customer::where('is_active', 'YES')
->with('sales')
->with('contacts')
->whereHas('last_contact', function ($q){
return $q->where('result', 'UNCALLED');
})->get();
Or that:
$customers = Customer::where('is_active', 'YES')
->with('sales')
->with('contacts')
->with('last_contact', function ($q){
return $q->where('result', 'UNCALLED');
})->get();
If you want you can declare last_contact with the additional where:
public function latest_contact()
{
return $this->hasOne(Contact::class)
->where('result', 'UNCALLED')
->latest('contact_date');
}
This way all other queries should be easier.
I hope this can help you.
I'm not sure, but can you try to do the following:
return Customer::where('is_active', 'YES')
->with([
'sale',
'contact' => function ($query) use($record) {
return $query->whereIn('id', $record)->where('result', 'UNCALLED');
}
])->get();
In my User model in Laravel 5.2 I have a relationship setup with their status to the company.
public function companyStatus()
{
return $this->hasOne('CompanyUser')->select('status');
}
The CompanyUser table has a company_id, user_id, and status field
Then in my controller I do the following:
$company = Company::find($company_id);
$users = CompanyUser::where('company_id', $company_id)->pluck('user_id')->toArray();
$user_data = User::with('companyStatus')->find($users);
but when I dump the user_data array it has all of the users related to the company, but just shows null for their status relationship
{
"id":2,
"name":"Moderator",
"email":"mod#company.com",
"created_at":"2016-09-08 15:26:20",
"updated_at":"2016-09-08 15:26:25",
"company_status":null
}
If I however return just the User collection to the view, and iterate over each user and run
$user->companyStatus->status
the value displays, but I am trying to include this within the collection for a JSON API to consume.
UPDATE
I tried adding the foreign key to the select call on my relationship method:
public function companyStatus()
{
return $this->hasOne('CompanyUser')->select('status', 'user_id');
}
and it now returns the following:
{
"id":2,
"name":"Moderator",
"email":"mod#company.com",
"created_at":"2016-09-08 15:26:20",
"updated_at":"2016-09-08 15:26:25",
"company_status": {"status":"1","user_id":"2"}
}
Not sure if this is the best/correct method or not though.
Okay I figured it out.
I tried adding the foreign key to the select call on my relationship method:
public function companyStatus()
{
return $this->hasOne('CompanyUser')->select('status', 'user_id');
}
Then that returns:
{
"id":2,
"name":"Moderator",
"email":"mod#company.com",
"created_at":"2016-09-08 15:26:20",
"updated_at":"2016-09-08 15:26:25",
"company_status": {"status":"1","user_id":"2"}
}
Without the foreign key Laravel obviously can't determine the related data on the other table.