I have this user table
id | name | email | department_id
1 user 1 xyz#gmail.com 2
and this is department table
id | department_name
1 Admin
2 Account
there is salary table :
id | user_id | basic_pay
1 1 5000
I have this employee relation in salary model
class Salary extends Model
{
public function employee(){
return $this->belongsTo('App\User','user_id','id');
}
}
I want to get department name also to which user is associated
$Data = Salary::where('id',$id)->with('employee')->first();
but presently i can only get department_id with the help of employee relation.
Any help is highly appreciated.
You could add another relationship to the User model called department which would look like this:
public function department()
{
return $this->belongsTo(Department::class);
}
and then user dot notation documented here: https://laravel.com/docs/8.x/eloquent-relationships#nested-eager-loading. Which would look like this
Salary::where('id', $id)->with('employee.department')->first();
Additionally, you can simplify this by using the find method, which would look like this:
Salary::with('employee.department')->find($id);
You would need to reverse the other of methods due to the fact that find will return the model, in this case a Salary model.
If you do not know if the Salary will exist you may want to use findOrFail documented here https://laravel.com/docs/8.x/eloquent#not-found-exceptions
Data = Salary::where('id',$id)->with('employee.department')->first();
In Your Employee model add relation like Below
public function department(){
return $this->belongsTo('App\Department','department_id');
}
Related
I have a bookmark system. Where user can bookmark a forum & feed.
I am trying to use a polymorphic relationship. But I can't figure out how to use user_id with polymorphic relations. I want to use eloquent to fetch all feed bookmarks & forum bookmarks separately for a user. I am confused about what relationship to use where!
Business rules I want to achieve -
User can Bookmark Many Feed & Forum
Feed & Forum can be Bookmark by User
//Users table
id ----- name ----- email ----- password
//Feeds table
id ----- title ----- description
//Forums table
id ----- title ----- description
//Bookmarks table
id ----- user_id ----- bookmarkable_id ----- bookmarkable_type
User model
class User extends Authenticatable
{
public function bookmarks(){
return $this->hasMany('App\Models\Bookmark');
}
}
Bookmark model
class Bookmark extends Model
{
public function bookmarkable(){
return $this->morphTo();
}
}
Feed model
class Feed extends Model
{
public function bookmarked_by(){
return $this->morphToMany('App\Models\User', 'bookmarkable');
}
}
Here's what I want to achieve, we have Staff and every staff can have one Position for a department, as well as one Designation for a department and multiple Additional Charges for multiple departments, one department per Additional Charge. And I want to store all the responsibilities in the staff_responsibilities table
I have a staff table with the following columns
id
name
email
Then I have staff_responsibilities table with the following columns:
staff_id
designation_id
department_id
responsibility_type_id
Responsibility types can be Position and Additional Charge and one staff can have multiple designations with Additional Charge responsibility.
Then I have a responsibility_types table with the following columns:
id
name
// I have no way to tell this relationship to look for a responsibility type 2 (2 is the id of the responsibility called `Designation`)
public function designation()
{
return $this->hasOne(StaffResponsibility::class);
}
// I have no way to tell this relationship to look for a responsibility type 2
public function position()
{
return $this->hasOne(StaffResponsibility::class);
}
// Gives error: Syntax error or access violation: 1066 Not unique table/alias: 'staff_responsibilities'
public function additionalCharges()
{
return $this->belongsToMany(StaffResponsibility::class, 'staff_responsibilities','designation_id');
}
Any help would really be appreciated.
staff_responsibilities table
responsibility_types table
designations table
Here's what I want to achieve, we have Staff and every staff can have one Position for a department, as well as one Designation for a department and multiple Additional Charges for multiple departments, one department per Additional Charge.
It sounds to me like it would be beneficial to create a model for Position, Designation and Additional Charges. It feels like you may need to normalize your database or to change staff_responsibilities as a pivot table.
But hard to say without knowing your application.
To answer your question, you could add some scopes in StaffResponsibility
class StaffResponsibility extends Model{
public function scopeDesignation($query)
{
return $query->where('responsibility_type_id','=',2);
}
}
and use it
public function designation()
{
return $this->hasOne(StaffResponsibility::class)->designation();
}
And the last one is a hasMany relation and not a manyToMany according to what you wrote:
public function additionalCharges()
{
return $this->belongsTo(StaffResponsibility::class, 'staff_responsibilities','designation_id')->additionalCharges();
}
I have a problem with laravel relationships.
I have 3 models:
City —(hasMany) —>Clinic—(hasMany) —>Stock
Stock —(belongsTo) —>Clinic —(belongsTo) —>City
I need get all cities which has stocks, looks like «Stock->cities». I can write sql-query:
SELECT ct.id, ct.name
FROM CfgCity as ct
RIGHT JOIN lr_clinics AS cl ON(ct.id=cl.city_id)
RIGHT JOIN lr_clinic_stocks AS st ON(cl.id=st.clinic_id)
WHERE st.deleted_at IS NULL
GROUP BY ct.id
But I want decision in laravel-orm, because it’s more readable and I don’t need write names of rows and tables. Is it possible?
Thanks.
From your question it is clear that city has relation with clinic and clinic has relation with stock that means city has relation with stock through clinic. That you can define it using laravel relationship.
City Model
class City extends Model {
public function clinics(){
return $this->hasMany(Clinic::class);
}
public function stocks(){
return $this->hasManyThrough(Stock::class, Clinic::class);
}
}
Fetch data
$cities = City::whereHas('stocks')->get();
For details you can check https://laravel.com/docs/5.6/eloquent-relationships#has-many-through
I have a quick question on how to define the below relationship
I have a USER that can belong to Many Councils, Many Schools and Many Businesses.
Now I know I can have a pivot table for all the above something like
council_user
school_user
business_user
This means I can pull out of the DB all councils a user belongs to, all businesses etc
To save me doing this is there a better approach that having 3 pivot tables, could I use Many To Many Polymorphic Relations and do it that way, if so does any one know how that would look as a table structure?
I feel it would be something like...
business
id - integer
name - string
council
id - integer
name - string
school
id - integer
name - string
userables
user_id - integer
userable_id - integer
userable_type - string
If so do I remove the userable_is and userable_type from my USER table and have this extra userables table?
Does any one know how this works, have I totally misunderstood what Polymorphic Relations does?
In Many to Many polymorphic relationship, you should have userables table along with users table. and userable_id and userable_type should be in userables table not in users table.
userables table:
user_id userable_id userable_type
1 1 App\Business
1 2 App\School
...
Business, School and Council Model:
public function users()
{
return $this->morphToMany('App\User', 'userable');
}
User Model:
public function businesses()
{
return $this->morphedByMany('App\User', 'userable');
}
public function schools()
{
return $this->morphedByMany('App\User', 'userable');
}
public function councils()
{
return $this->morphedByMany('App\User', 'userable');
}
then, this gives all the businesses of user with user_id 1.
$users=User::find(1);
foreach($user->businesses as $business)
{
print_r($business->name);
}
See Many to many polymorphic relation in doc.
TL:DR;
City model - Locations model - Offers model.
1 city hasMany locations, locations belongToMany offers
City::with('locations.offers')->where('slug','=', $city)->first();
shows 0 offers from relation even though there is an offer record connected to location (which is connected to the city).
Longer version:
I have 3 models which should be connected to each other. City, Location & Offer.
I have the given city, and want to retrieve all locations with offers which are connected to the city. In the output of:
City::with('locations.offers')->where('slug','=', $city)->first();
I see the city and all locations connected to the city. Each location has an empty offer relation.
Model City:
class City extends Model
{
public function locations()
{
return $this->hasMany('App\Location');
}
}
Model Location
class Location extends Model
{
public function city()
{
return $this->belongsTo('App\City');
}
public function offers()
{
return $this->belongsToMany('App\Offer','location_offer','offer_id','location_id');
}
}
Model Offer
class Offer extends Model
{
public function locations()
{
return $this->belongsToMany('App\Location','location_offer','offer_id','location_id');
}
}
Database is pretty basic:
city table holds the city information (id+title)
location table has city_id (and location title)
location_offer table has location_id & offer_id
offer has offer information.
Clearly I'm doing something wrong, but can't seem to figure it out. Any tips would be greatly appreciated.
Your code is perfect there is a small mistake in your relation
public function offers()
{
return $this->belongsToMany('App\Entities\Offers','location_offer','location_id','offer_id');
}
You need to check this link the third argument is wrong
The third argument is the foreign key name of the model on which you are defining the relationship, while the fourth argument is the foreign key name of the model that you are joining to:
Check the Queries
This is the one that will be executed by your code
select `offer`.*, `location_offer`.`offer_id` as `pivot_offer_id`, `location_offer`.`location_id` as `pivot_location_id` from `offer` inner join `location_offer` on `offer`.`id` = `location_offer`.`location_id` where `location_offer`.`offer_id` in ('1', '2')
See join is wrong :
join location_offer on offer.id = location_offer.location_id
This is the right one
select `offer`.*, `location_offer`.`location_id` as `pivot_location_id`, `location_offer`.`offer_id` as `pivot_offer_id` from `offer` inner join `location_offer` on `offer`.`id` = `location_offer`.`offer_id` where `location_offer`.`location_id` in ('1', '2')
join location_offer on offer.id = location_offer.offer_id