accessing relationship from model laravel - php

i have a two tables where user table has a one to one relationship with role table
this is my user model
public function role(){
return $this->belongsTo(Role::class);
}
this is my role model
public function user(){
return $this->hasOne(User::class);
}
this my table structure for role
this my table structure for user
how can i access in my user model the role which is equal to employee
i tried
User::with('role')->where('role_name','employee')->get();
but it has an error
role_name column not found

This will give you only the users which has an employee role .
User::whereHas('role', function ($query) {
$query->where('role_name', 'employee');
})->get();
And this will give you all the users with their employee roles if any exist
User::with(['role' => function ($query) {
$query->where('role_name', 'employee');
}])->get();

Try this:
User::whereHas('role', function ($query) {
$query->where('role_name', 'employee');
})->get();
Details at: https://laravel.com/docs/5.4/eloquent-relationships#querying-relationship-existence

Try this:
User::with(['role' => function ($query) {
$query->where('role_name', 'employee');
}])->get();

Related

How can I make Laravel eloquent relationship with multiple tables?

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

Laravel Check column using relationship column

I need to query and check if the relationship column is the same in my main table column.
example codes:
not working
User::with('product', => function($q) {
$q->whereRaw('users.company_id',' product.company_id');
})->get();
not working
User::with('product', => function($q) {
$q->whereRaw('users.company_id = product.company_id');
})->get();
not working
User::with('product')->whereColumn('users.company_id', 'product.company_id')->get();
but it's not working..
any idea how to do it?
My Models
User Model
public function product()
{
return $this->belongsTo(Product::class, 'product_id');
}
Product Model
public function users()
{
return $this->hasMany(User::class, 'product_id');
}
Please try again:
User->with(['product' => function ($query) {
$query->join('users', 'users.company_id', '=', 'product.company_id');
}])->get();
Try to use DB:raw() then show the table info? like this

How to connect already connected table with other table in laravel?

I have a user table it has one userRole and userRole belongs to Role. So, I want to fetch the userRole and Role also.
Code in user Model:
public function userRole()
{
return $this->hasOne(UserRole::class);
}
Code in UserRole model:
public function role()
{
return $this->belongsTo('App\Role');
}
Code in controller:
User::with('userRole', function ($role) {
$role->with(['Role']);
})
->wherehas('userRole', function ($query) {
$query->where('role_id','1');
})->get();
This is giving me error
"mb_strpos() expects parameter 1 to be string"
The problem is that you should pass an array when you want to add a constrait to the with() method.
Your code should like something like:
User::with([
'userRole' => function ($query) {
...
}
])
...

Laravel - order by number of entries

This is a follow up from this question. I have a query that looks like this:
$users = User::leftjoin('role_user', 'users.id', '=', 'role_user.user_id')
->select('users.*')
->orderBy(DB::raw('role_id IS NULL'))
->groupBy('users.id')
->orderBy('role_id', 'asc')
->get();
When I do it like that I get distinct values for users, and they are ordered by role_id in asc order, the only thing with this query is that users that have two or more roles are behind the ones with who have only one role. For example, user has roles with id=1 and id=2, and other user has a only a role with id=1, that user will be before the user with two roles in the list. I would like to change that and have users with more roles above the ones with only one role.
I would recommend to use Query Scopes and Querying Relations
class User extends Authenticatable
{
...
public function roles()
{
return $this->belongsToMany('Role', 'role_user');
}
// Scope users who have a specified role
public function scopeHasRole($query, $role) {
return $query->whereHas('roles', function ($q) use ($role) {
$q->where('id', $role);
});
}
// Scope users who have a set of roles
public function scopeHasRoles($query, $roles) {
if (! is_array($roles)) {
return $this->scopeHasRole($query, $roles);
}
return $query->whereHas('roles', function ($q) use ($roles) {
$q->whereIn('id', $roles);
});
}
// Scope a user who don't have any roles.
public function scopeDoesntHaveAnyRoles($query) {
return $query->whereDoesntHave('roles');
}
}
Example usage:
User::doesntHaveAnyRoles(); // return users don't have any roles.
User::hasRole(1)->orderBy('id', 'asc')->get(); // return users who belongs to role id 1.
User::hasRoles([1, 2, 3]); // return users who have a set of roles.
Following query worked for me in the end:
User::leftjoin('role_user', 'users.id', '=', 'role_user.user_id')
->select('users.*')
->selectRaw('user_id, count(*) as count')
->orderBy(DB::raw('role_id IS NULL'))
->groupBy('users.id')
->orderBy('count', 'DESC')
->orderBy('role_id', 'asc')
->get();

Laravel 5.1 eloquent query syntax

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

Categories