Laravel get related data from 3 tables - laravel

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.

Related

Display relationship of relationship in response

My stack is - Laravel, React, Vite. I have a relationship:
$messages = $user->profile->messages
and it works correctly, but messages have relationship with user. Propably it sound difficult but it's simple.
Profile contains more details about user and profile has relationsin hasMany for Messages. It's simple. But I need to display messages with username (this is in Username model). How I said Messages have an relationship with User model but it's not in my response.
public function user() {
return $this->belongsTo(User::class);
}
If I want to display only data from model with relationship I could use with, for example:
Book::with('author')->get()
But in this case it didn't work. For example
$user->profile->messages->with('user')
It display me the error
Method Illuminate\Database\Eloquent\Collection::with does not exist.
My question is - how could I add relationship (to user) to this query so that I can see that relationship in the response?
$user->profile->messages
not sure what query you are using, but you can write something like this if you wish which should work assuming that the messages and user relationships are correctly defined
$user = User::with(['profile',
'profile.messages',
'profile.messages.user:id,username'])
->where(//some condition)->get()

Laravel: Pull data from multiple tables

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

How to limit access from pivot table? Laravel

I have tables:
user
id
name
companies
id
name
company_user
company_id
user_id
Tables has Many To Many relationships.
As it complicated relationship for me, I can't find way how to make this limit, when user can see companies that was created by this user. (probably not well experienced)
Now I have this, but user can see any company
CompanyController:
public function show($company_id)
{
$company = Company::where('id', $company_id)->firstOrFail();
return view('company.settings', compact('company'));
}
So tip me please how to make user can see only companies created by this user.
You can do this:
public function show($company_id)
{
$company = auth()->user()->companies()->findOrFail($company_id);
return view('company.settings', compact('company'));
}
It will scope the company to the currently logged in user (through the many-to-many relationship on the User model). If none is found, it will return 404.
Since it many to many relation, you can map one company to many users, also map one user to many companies. Check if you have not mistakenly assign the company to many user
Also the above code can be written the way
public function show($company_id)
{
$company = Company::findOrFail($company_id);
return view('company.settings', compact('company'));
}

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);

Create multiple objects from api post in laravel

Im at a bit of a loss. I have an api that will create a user upon a request. This is done no problem.
I also want to create another controller action or add to my current action the ability to create an address for the same user.
Is there an easy way to do this? Or should I stick to the
$user = new User(Input::all());
$user->save();
$address = new Address(Input::all());
$address->save();
You should set up relationships between your User and Address model - http://laravel.com/docs/eloquent#relationships and use associate/sync() to connect the dots.
This is a relationship problem. An address to a user will most likely be One-to-One (i.e., each Userhas a unique Address). A User might have an Address, but an Address must have a User. So in essence, the Address belongs to User.
Create two tables users and addresss, and add user_id to the address table as a column.
Then you define your relationships:
// In your User.php model
public function address()
{
return $this->hasOne('Address');
}
// In your Address.php model
public function user()
{
return $this->belongsTo('User');
}
Note when you use the correct notation, you can just define the model name, and not specify the pivot column. That is why I have defined the class addresss with an extra 's' to make it plural. I personally don't care about the spelling and rather Laravel take care of everything. Otherwise read the documentation on how to define the pivot column
Then you can use associate easily:
$user = new User();
// Fill $user however you want
$address = new Address();
// Fill $address however you want
$user->associate($address);
$user->save();
I was able to figure it out!
I wound up utilizing the Ardent package to help me validate my models before they hit the save method.
if my models didnt validate i will return all the errors to the user.
If they did validate my models would be created.
As for the association I am using the has many relation ship on the User and belongs to on the Address.
I used the following to save the address to the user
$address = $user->address()->save($address);
however I could only preform this after the initial user object was saved.
Thanks for all the responses guys they lead me in the right direction!

Resources