Pulling a value from related table in a controller - model-view-controller

I'm using Yii2 framework for the first time, trying to implement it in a project.
I've got a dropdown list of customers where i'd like to also show customer's company next to customer's name.
Customer and Company tables are related. Here's what it looks like in a Customer model:
public function getCompany()
{
return $this->hasOne(Company::className(), ['id' => 'company_id']);
}
So now i'm forming a dropdown list containing customer's name, email, phone and company name. Name, email, and phone belong to one table, so there's no problem with pulling them together. Here's what it looks like in Customer model:
public function getfullInfo()
{
return $this->name.' '.$this->phone.' '.$this->email;
}
I don't really understand this framework's logic. How do I pull in Company's name in above code?
Thank you guys.

Here's the correct code:
public function getfullInfo()
{
return $this->name.' '.$this->phone.' '.$this->email.' '.$this->company['name'];
}
This was so easy and I've wasted so much time on this.

Related

Category name on post

On my posts page, I want to display the category name rather than the ID. I've tried searching and trying every solution I can find here but still struggling, so any help would be massively appreciated.
In my policy resource controller, I have:
public function show(Policy $policy)
{
return view('policies.show',compact('policy'));
}
In my Policy model, I've got.
public function category()
{
return $this->belongsTo(Category::class);
}
I've got cat_id in my policies table, and in my categories table, it is id and category_name. So, of course, I can show the category ID on the policy page by doing the following.
{{ $policy->cat_id }}
But I need to convert that into the category name. I know this is a basic question, but I've only recently started getting into Laravel. I have done a lot of searching, and none of the solutions seem to work for me.

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

Laravel retrieving single related attribute

I have a laravel app that allows users to post posts. Each post has a price (stored as an integer), and belongs to a university, which in turn belongs to a country, which has a currency.
Every-time I retrieve the posts, I want to return the currency as well. I could do with('university.country') but that would return all the details for both the university and country.
I could add a getCurrencyAttribute and define the logic there, but that seems not what mutators are for, especially since if I get all the posts, each post will further run two of its own queries just to get the currency. That's 3 queries to get one post, which quickly takes its toll when returning more than 10 posts.
public function getCurrencyAttribute() {
return $this->university->country->currency;
}
public function getPriceAttribute($value) {
return "{$this->currency}{$value}";
}
^ example above: no need for appends because price is automatically overwritten. This is the problem as seen on DebugBar (two new queries are being called on the Post model, which while expected, becomes inefficient when retrieving lots of posts):
What's the best way to get a single related field, every-time?
Full code on GitHub.
You can limit the eager loading columns:
Post::with('webometricUniversity:uni-id,country_id',
'webometricUniversity.country:id,currency')->get();
If you always need it, add this to your Post model:
protected $appends = ['currency'];
protected $with = ['webometricUniversity:uni-id,country_id',
'webometricUniversity.country:id,currency'];
public function getCurrencyAttribute() {
return $this->webometricUniversity->country->currency;
}
Then you can just use Post::get() and $post->currency.

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

Has-Many-Through Relations

I have done a lot of research in Google about this. There are not a good examples with using this type of relation between models.
Can somebody share own sample using Has-Many-Through Relations in Laravel?
Let's take a sample of a social network where you have User, their Friends and their friends' Photos. 3 models. yep a friend is just a normal user but for this example, a Friend would be a separate Model.
1- A user has friends
public function friends() {
return $this->hasMany(Friend::class);
}
2 - A friend has photos
public function photos() {
return $this->hasMany(Photo::class);
}
3 - You are the admin. you have many users, including John. John has a lot a friends. So sometimes, you want to see John's friends photos, maybe those where they tag him. So in user you define the relationship
public function friendsPhotos() {
return $this->hasManyThrough(Friend::class, Photo::class); //could add a scope here for picture with tags only.
}
Not problably the best example. But it shows how you can see all John's friends pictures by just doing
$john = User::where('email', 'john#email.com')->first();
$john->friendsPhotos();
If the example doesnt suit you well, now think of a bank looking for their best salesperson in a specific Branch. A Branch hasMany Salesperson, and each Salesperson hasMany Customers they deal with.
In Branch model, you define
public function customers() {
return $this->hasManyThrough(Salesperson::class, Customer::class);
}
I hope this helps a little bit.
Database tables for the banking system
1- Branch
id
name
...
2 - Salesperson
id
branch_id
firstname
...
3 - Customer
id
salesperson_id
firstname
...

Resources