Laravel: Pull data from multiple tables - laravel

I am new to Laravel but I dont think Im writing optimised code. I am looking at getting all overdue invoices separated by clients. Invoices table and clients table. client_id is within the invoices table. I have the following below but I wanted to know if there is a better way. I would also want to grab the client name from the clients table. I have created an array so I can loop throgh accordingly on the view file, but again im not sure this is the correct way?:
$overdueClients = Invoice::where("date_paid",'0000-00-00')->where("date_due","<=",date("Y-m-d"))->pluck('client_id');
foreach($overdueClients as $overdueClient)
{
$invoices = Invoice::select("title","total","on_account","date","date_due")->where("date_paid",'0000-00-00')->where("date_due","<=",date("Y-m-d"))->where('client_id',$overdueClient)->get();
$return[$overdueClient][] = $invoices;
}
return $return;

yes luckily there is a better way for which term is called relations and can use eager loading so what you can do is to make relation is models first :
so in you Invoice model you write something like below :
public function users(){
return $this->belongsTo('App/Users');
}
you should fix the above relation according to the name and path of your model and in your users model :
public function invoices(){
return $this->hasmany('App/Invoices');
}
so now an invoice belongs to a user and a user can Have many Invoices . and when you need to get the users which has invoices and overdue invoices you do like below :
$users = Invoices::with('users')->where("date_paid",'0000-00-00')->where("date_due","<=",date("Y-m-d"));
this is the better way to act because of preventing n+1 problems this way you only load users if they have overdue invoices if not they are not being loaded at all take a look at documentation below :
https://laravel.com/docs/7.x/eloquent-relationships#introduction
i strongly recommand to take time and read this and practice it as you would need it more that you think when you want to work with laravel . hope this helps

Related

How to search for all associations in a relationship tree in Laravel?

I'm having a problem. I have tables that relate:
internal_clients->subsidiaries->departments->job_titles->users
I also have their respective models.
My doubt is:
How do I get all the data associated with users from the top of the tree (internal_clients)
?
I'm trying to follow the Laravel documentation using hasManyThrough.
However, in the documentation it explains only how to do it in a chain of three tables. They teach how to place an intermediate table (model) as the second parameter of the hasManyThrough method (BaseClasse::class, IntermediaryClass::class).
However, in my case that has several tables between users and internal_clients, how would I do this? What would be the intermediate table?
I would like to make a query that returns the user's internal_client, subsidiary, department and jobTitle (associated with users).
I'm trying to do it this way:
Model InternalClient
public function users()
{
return $this->hasManyThrough(User::class, InternalClient::class);
}
Controller UserController
public function allRelations($internalClientId)
{
$internalClient = InternalClient::find($internalClientId);
$users = $internalClient->users;
return response()->json($users, 201);
}
The InternalClient id arrives at the controller above.
When I access the route, the error below is returned:
In short: I would like to know if there is a way to get all the data (from all tables that are in this hierarchical tree) that are associated with the User.
I couldn't find an answer on the Stackoverflow PT-BR.
Thank you!

Laravel relationships to tables

Quite new to Laravel and learning it now for work and just wonder, why do you have to use relationships, when you can simply use?
$n = Name::find(2)
$a = Address::where('name_id', '=', $n['id'])->get()
Instead of forming a relationship in the controller and:
$n = Name::find(2)
$n->address
Is it to less complicated somehow or is it just to reduce code or what?.
Any help appreciated and thanks in advance.
It is to write less code and to encapsulate things (write once and use everywhere)... those are the main principles in OOP... Your example is not so complicated. If a user has only one address you don't even need a separate model for adress, just put it in users table as an attribute...but imagine a relationship a Customer and Invoice... a Customer can have multiple Invoices and you want to show all invoices (with all the details) of a certain Invoice. It would require of you to write a lot of code to show all the details without making relationships between the models.
İf users have one adress, you dont need to new model. Just add 'address' column in your users table;
Here is your migration;
php artisan make:migration add_address_column_to_users_table
İf users have multiple adress, you can use one to many releationships.
Create address model and table,
php artisan make:model Address -m
Then in your Address model, add this function;
public function users()
{
return $this->belongsTo('App\User');
}
And in your User model;
public function address()
{
return $this->hasMany('App\Address');
}
Thats all. You can fnd more information in here

Eloquent relationship for multiple table

I am working in laravel5.4. I have created four table as ticket, users, and company. Here, I have stored users id in ticket table. And stored company id in users table.
Here, I want to show ticket's user name with that users company name.
Here, I have create relation for it that looks like below.
Ticket model :
public function requesters(){
return $this->belongsTo('App\User','requester_id');
}
Here requester_id is who create ticket.
Users model :
public function company()
{
return $this->belongsTo('App\Models\Admin\Company');
}
Company model :
public function Users()
{
return $this->hasOne('App\Users');
}
Here, I have written query to get users information that looks like below.
Ticket::with('requesters')->orderBy('subject','asc')->paginate(10);
Now, I want to fetch company information or request_id So what changes should I have to do in this query to fetch company info along with ticket and users ?
If you want to to Eager load multiple relationship you can put them all in single with like this:
Ticket::with('requesters','requesters.company')->orderBy('subject','asc')->paginate(10);
but if you load nested relationship you can use shorter notation - you can omit parent relationship, so it's enough to use here:
Ticket::with('requesters.company')->orderBy('subject','asc')->paginate(10);
Try this, it should work for this case:
Ticket::with('requesters')
->with('requesters.company')
->orderBy('subject','asc')->paginate(10);

Laravel get related data from 3 tables

I have three tables: users, emails,attachments. User table is connected with emails by user_id. Emails table is connected with attachments by email_id.
My question is: How should I make it look eloquent in laravel to get all users their emails and their attachments? (I know how get all user and they emails but I don't know how to add attachments.)
Depending on your database relationship,you may declare a relationship method in your Email model, for example:
// One to One (If Email has only one attachment)
public function attachment()
{
return $this->hasOne(Attachment::class);
}
Otherwise:
// One to Many (If Email contains more than one attachment)
public function attachments()
{
return $this->hasMany(Attachment::class);
}
To retrieve the related attachment(s) from Email model when reading a user using id, you may try something like this:
$user = User::with('email.attachment')->find(1); // For One-to-One
$user = User::with('email.attachments')->find(1); // For One-to-Many
Hope you've already declared the relationship method in the User model for Email model using the method name email.
Note: make sure, you have used right namespace for models. It may work if you've done everything right and followed the Laravel convention, otherwise do some research. Also check the documentation.

Querying multiple table to get specific data with Eloquent ORM

I am quite new to Laravel 4 and its great Eloquent ORM. I have four tables such as :
Sector (iSectorCode);
MailingSector (iSectorCode, iMailingCode);
Mailing (iMailingCode);
MailingLanguages(iMailingCode, sTranslation);
I have the sector id, and I want to get all Mailings associated. But I also need to reach the MailingLanguages table containing the content translations for a specific Mailing.
So for now I can get all Mailings for a specific sector doing :
Sector::find($iSectorCode)->mailings()->get()->toArray();
But doing Sector::find($iFormSectorCode)->mailings()->mailingsLanguages()->get()->toArray(); don't work even if the relation between Mailing and MailingLanguages is defined :
public function mailingsLanguages(){
return $this->hasMany('MailingLanguage','iMailingCode');
}
So I don't know how to get all translations for a specific Mailing, for a specific Sector.
Providing that you've setup relationships between all of the tables, you can request that they be grabbed with the initial request.
$sector = Sector::with('mailings', 'mailings.languages')->find($iSectorCode);
This will create a nice join that will include related records for Mailing, then their related records for MailingLanguage, as well as the requested Sector.
The above example does assume that Sector has a relationship called mailings and that Mailing has a relationship called languages.
You could also load them in after the fact.
$sector = Sector::find($iSectorCode);
$sector->load(['mailings', 'mailings.languages']);
I would recommend making use of the findOrFail method that laravel provides.
try {
$sector = Sector::with(['mailings', 'mailings.langauges'])
->findOrFail($iSectorCode);
} catch(ModelNotFoundException $e) {
// do something here
}
This saves having to check whether $sector returned anything, as an exception will be thrown.
Hope that helps.

Resources