I am trying to make 3 tables relationship like this,
users
id
name
roles
id
name
companies
id
name
company_role_user
user_id
role_id
company_id
Relationships in User.php model
public function companies() {
return $this->belongsToMany(Company::class, 'company_role_user', 'user_id', 'company_id');
}
public function roles() {
return $this->belongsToMany(Role::class, 'company_role_user', 'user_id', 'role_id');
}
public function role() {
// relationship to get role of specific company
}
Relationships in Company.php model
public function users() {
return $this->belongsToMany(User::class, 'company_role_user', 'company_id', 'user_id');
}
public function roles() {
return $this->belongsToMany(Role::class, 'company_role_user', 'company_id', 'role_id');
}
public function role() {
// relationship to get role of specific user
}
I want to get user role for specific company like this
User::find(1)->companies[0]->role->name
or
Company::find(1)->users[0]->role->name
If you have users
users
– id
– name
and you want them to have many to many relation with companies, you should do:
companies
– id
– name
user_companies
– user_id
– company_id
And for your roles, (many to many) you can do the same:
roles
- id
- name
user_roles
- user_id
- role_id
You are trying to make many to many 3 tables, when you should be doing it with 2 tables.
Even if you manage, it would be very complicated and confusing.
You should consider which tables should be related to roles, companies should have roles, or users should have roles, you dont need them both to have roles
Your schema looks correct but your model definitions/relations can use a junction/pivot model CompanyRoleUser which will relate these 3 relations as many-to-one/belongsTo and one-to-many/hasMany from Company/Role/User.
class Company extends Model
{
public function companyRoleUser()
{
return $this->hasMany(CompanyRoleUser::class, 'id', 'company_id');
}
}
class Role extends Model
{
public function companyRoleUser()
{
return $this->hasMany(CompanyRoleUser::class, 'id', 'role_id');
}
}
class User extends Model
{
public function companyRoleUser()
{
return $this->hasMany(CompanyRoleUser::class, 'id', 'user_id');
}
}
class CompanyRoleUser extends Model
{
public function company()
{
return $this->belongsTo(Discipline::class, 'id', 'company_id');
}
public function role()
{
return $this->belongsTo(Speciality::class, 'id', 'role_id');
}
public function user()
{
return $this->belongsTo(User::class ,'id','user_id');
}
}
Now you can apply different type of filters for your data like
Fetch users for company A id = 1 with admin role id = 2
User::whereHas('companyRoleUser.company', function ($query) use ($company_id) {
$query->where('id', $company_id);
})->whereHas('companyRoleUser.role', function ($query) use ($role_id) {
$query->where('id', $role_id);
});
Or
User::whereHas('companyRoleUser', function ($query) use ($company_id) {
$query->where('company_id', $company_id)
->where('role_id', $role_id);
});
Fetch companies with $user_id and $role_id
Company::whereHas('companyRoleUser', function ($query) use ($user_id) {
$query->where('user_id', $user_id)
->where('role_id', $role_id);
});
Related
I have 2 models: one for users and one for clients. A user is a customer
User has a 'codigocli' field and client has a 'codigo' field
The relationships between my models are like this:
//User model
public function cliente()
{
return $this->hasOne(Cliente::class, 'codigo', 'codigocli');
}
//Cliente model
public function user()
{
return $this->belongsTo(User::class, 'codigocli', 'codigo');
}
My database is fine (I think) client has the 'codigo' field and users has the 'codigocli' field. So what am I doing wrong? When I want to query my home.blade.php with dd(auth()->user()-cliente()) I don't get anything, although it shows me the parent object fine.
H
You have an OneToOne relationship here so try this if you don't change id name:
//User model
public function cliente()
{
return $this->hasOne(Cliente::class, 'codigocli');
}
//Cliente model
public function user()
{
return $this->belongsTo(User::class, 'codigocli');
}
if you change id name:
//User model
public function cliente()
{
return $this->hasOne(Cliente::class, 'codigocli','local_id_name' );
}
//Cliente model
public function user()
{
return $this->belongsTo(User::class, 'codigocli', 'local_id_name');
}
We are trying to build an application in Laravel 8 where we need to fetch some data through complex queries. Let me explain my model structure to you:
I have a Brand model, which is related to multiple Group and SubGroup model with many-to-many relation. Each brand is associated with multiple Project with respect to Group and SubGroup model.
So my Brand model looks like:
public function group()
{
return $this->belongsToMany(Group::class, 'brand_group', 'brand_id', 'group_id');
}
public function subgroup()
{
return $this->belongsToMany(SubGroup::class, 'brand_subgroup', 'brand_id', 'sub_group_id');
}
public function projects()
{
return $this->belongsToMany(Project::class, 'project_associate_brand', 'brand_id', 'project_id');
}
I've a pivot table project_associated_brand which has project_id, group_id, sub_group_id, brand_id
Considering the pivot table I've defined the relationship in Project, Group and SubGroup:
Project model:
public function brand()
{
return $this->belongsToMany(Brand::class, 'project_associate_brand', 'project_id', 'brand_id');
}
public function group()
{
return $this->belongsToMany(Group::class, 'project_associate_brand', 'project_id', 'group_id');
}
public function subgroup()
{
return $this->belongsToMany(SubGroup::class, 'project_associate_brand', 'project_id', 'sub_group_id');
}
Group model:
public function projects()
{
return $this->belongsToMany(Project::class, 'project_associate_brand', 'group_id', 'project_id');
}
public function brand()
{
return $this->belongsToMany(Brand::class,'brand_group',
'group_id', 'brand_id')->withTimestamps();;
}
SubGroup model:
public function projects()
{
return $this->belongsToMany(Project::class, 'project_associate_brand', 'sub_group_id', 'project_id');
}
public function brand()
{
return $this->belongsToMany(Brand::class,'brand_subgroup',
'sub_group_id', 'brand_id')->withTimestamps();;
}
I want to extract Project count from SubGroup with respect to each Brand
return SubGroup::with(['group', 'brand.projects' => function($q) {
$q->where('projects.status','saved');
}])->get();
Currently I'm getting the output:
[ {sub_group_name: 'abc subgroup', brands: [ {brand_name: 'lddf', project_count: 10}, {brand_name: 'uoweyr', project_count: 21}]} ]
Currently I'm getting all the projects count related to brands. I need to filter them too with respective SubGroup models also, what I expect the output:
[ {sub_group_name: 'abc subgroup', brands: [ {brand_name: 'lddf', project_count: 8}, {brand_name: 'uoweyr', project_count: 16}]} ]
Here project_count is filtered as per the Brand and SubGroup
You need to pass the where callback function to both the relation and the parent query:
$fn = function($q) {
$q->where('projects.status','saved');
};
SubGroup::with(['group', 'brand.projects' => $fn])->whereHas('brand.projects', $fn)->get();
you can use where Has call back function , this method allow you to write a query as Project model
read more from here :
[1]: https://laravel.com/docs/8.x/eloquent-relationships
I have 3 tables users companies company_users when I try to get user company details it return null
Logic
company has many users
user belong to 1 company
user model
public function company()
{
return $this->belongsTo(Company::class, 'company_users', 'user_id', 'company_id');
}
company model
public function user()
{
return $this->belongsToMany(User::class, 'company_users', 'company_id', 'user_id');
}
any idea?
it's not one to many relation it's many to many, with pivot table (company_users )
so, the relation should be like:
public function company()
{
return $this->belongsToMany(Company::class, 'company_users', 'user_id', 'company_id');
}
I recommend rename it to 'companies' cause it plural
Regarding to this comment:
If you really want one to many relation. Try this:
public function company()
{
return $this->hasMany(User::class);
}
public function user()
{
return $this->belongsTo(Company::class);
}
I have the following model relationships. If a user logs in as an employee, I want them to be able to get a list of employees for a their company and the roles they have been assigned:
class User {
// A user can be of an employee user type
public function employee()
{
return $this->hasOne('App\Employee');
}
//
public function roles()
{
return $this->belongsToMany('App\Role');
}
}
class Employee {
// employee profile belong to a user
public function user()
{
return $this->belongsTo('App\User');
}
// employee belongs to a company
public function company()
{
return $this->belongsTo('App\Company');
}
}
class Company {
public function employees()
{
return $this->hasMany('App\Employee');
}
}
But the following query doesnt work. I get error Column not found: 1054 Unknown column companies.id in WHERE clause:
$employee = Auth::user()->employee;
$companyEmployees = Company::with(['employees.user.roles' => function ($query) use ($employee) {
$query->where('companies.id', '=', $employee->company_id)
->orderBy('users.created_at', 'desc');
}])->get();
The users and the employees table have a one to one relationship.
All employees have a base role type of employee in addition they may also have other roles such as manager, supervisor etc.
How do I write a query that gives me a company with all its employees and their roles?
I've tried to add a hasManyThrough relation to the Company model but that doesn't work either?
public function users()
{
return $this->hasManyThrough('App\User', 'App\Employee');
}
I think you're ring to get a list of coworkers for the current user and eager load the user and role?
$employee = Auth::user()->employee;
$companyEmployees = Company::with(['employees.user.roles')->find($employee->company_id);
Or perhaps:
$companyEmployees = Company::find($employee->company_id)->employees()->with('user.roles')->get();
$sorted = $companyEmployees->sortBy(function($employee){ return $employee->user->created_at; });
That might be a more direct route. Is your employee id in the user table or vice versa? The eloquent relationships are easy to set backwards.
Users::select('table_users.id')->with('roles')->join('table_employes', function($join) use ($employee) {
$join->on('table_employes.user_id','=','table_users.id')->where('table_employes.company_id', '=', $employee->company_id);
})->orderBy('tables_users.created_at')->get();
1. Create relationship for database table columns in migrtaion :
User Role
$table->foreign('user_id')->references('id')->on('users');
Users
$table->increments('id');
2. Create a model for each database table to define relationship
User.php (model)
public function userRoles()
{
return $this->hasOne('App\UserRoles', 'user_id', 'id');
}
Userroles.php (model)
public function user()
{
return $this->belongsTo('App\User', 'user_id', 'id');
}
3. Let controller handle database calls recommended to use REST api
Controller
use App\User;
use App\UserRoles;
class UserController extends Controller
{
public function index()
{
return User::with('userRoles')->orderBy('users.created_at', 'desc')->paginate(50);
}
}
I have three tables: users, items and user_items. A user has many items and a item belongs to many users.
**Users**
id
username
password
**Items**
id
name
**User_items**
id
user_id
item_id
Models:
class User extends Eloquent {
public function items()
{
return $this->belongsToMany('Item', 'user_items', 'item_id', 'user_id');
}
}
class Item extends Eloquent {
public function users()
{
return $this->belongsToMany('User', 'user_items', 'user_id', 'item_id');
}
}
I need to select all items table, print it and highlight rows which belongs to specific user id=1.
Selection highlighted output:
What is the right way to do it (in laravel style)?
You can use it like this
public function user_items()
{
return $this->belongsToMany('User', 'user_items', 'user_id', 'item_id')->withPivot('id');
}
Like this you can access values of third table.
Some useful links-
http://www.developed.be/2013/08/30/laravel-4-pivot-table-example-attach-and-detach/
http://vegibit.com/many-to-many-relationships-in-laravel/
http://laravel.com/docs/4.2/eloquent
You can do it like this way...
class User extends Eloquent {
public function items()
{
return $this->belongsToMany('Item', 'user_items', 'item_id', 'user_id')->withPivot('id');
}
}
class Item extends Eloquent {
public function users()
{
return $this->belongsToMany('User', 'user_items', 'user_id', 'item_id')->withPivot('id');
}
}
From controller..
$user_id = 2;
Item::with(['users'=>function($q) use ($user_id){$q->where('user_id',$user_id);}])->get();
In view at the time of listing a row you can highlight the row just use a condition as each item->users is blank or not.