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);
}
}
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');
}
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);
});
I have a problem with related models.
There are three models. User, PostType (music, animals) and Post.
A user can select the posttypes he wants to see. So I created a pivot-table posttype_user.
Now I can save the selected postTypes binded to a user.
// User model
public function postTypes()
{
return $this->belongsToMany(PostType::class);
}
// PostType model
public function users()
{
return $this->belongsToMany(User::class);
}
The Post model has a foreign key with postType_id. And this relationships in the models:
// Post model
public function postType()
{
return $this->belongsTo(PostType::class);
}
// PostType model
public function post()
{
return $this->hasMany(Post::class);
}
Now I want to receive all Posts (of the selected posTypes) from the current user (Auth::user()).
But I don't know how. Does anyone have an idea?
You can use nested whereHas():
Post::whereHas('postType', function($q) {
$q->whereHas('users', function($q) {
$q->where('id', auth()->id());
});
})->get();
Or you can do this:
$postTypeIds = auth()->user()->postTypes()->pluck('id');
$posts = Post::whereIn('post_type_id', $postTypeIds)->get();
Hey how can I make relationships between two table.
Users: id, email
Notification: id, user_id(id of the logged user), client_id(id of sender)
I would like make relationship between users and notifications by user_id and client_id.
Then I will can get all notifications assigned to logged user, and get email of sender users.
I made that:
public function notifications_with_client() {
return $this->hasManyThrough('App\Models\User', 'App\Models\Notification', 'user_id', 'id', 'client_id');
}
But when I using query i got good notifications but with wrong email.
I got email from ralationship id(from users table) == id(from notifications table)
My query
$column = 'notifications_with_client';
$value[1] = ['email', 'notifications.id', 'client_id'];
$query->with([$column => function($query) use ($value) {
$query->select($value[1]);
}]);
Someone know what I do wrong?
You can try it by defining the following relations:
User Model
public function notifications()
{
return $this->hasMany('App\Models\Notification');
}
Notification Model
public function to()
{
return $this->belongsTo('App\Models\User', 'user_id');
}
public function from()
{
return $this->belongsTo('App\Models\User', 'client_id');
}
And then you can query it as:
$notifications = auth()->user()->notifications()->with('from')->get();
Or if you just want email then query it as:
$notifications = auth()->user()
->notifications()
->with(['from' => function($q) {
$q->select('email');
}])
->get();
public function user()
{
return $this->belongsTo(Users::class, 'user_id');
}
public function client()
{
return $this->belongsTo(Users::class, 'client_id');
}
With this code in your Notification Model you can get the logged user with
$this->user(); // $notification->user();
and the sender with
$this->client(); //$notification->client();
You cannot use $this->hasManyThrough(). It use for a different reason
You can use $this->belongsTo() like this.
class User extends BaseModel
{
public function user()
{
return $this->belongsTo(Notification::class, 'user_id');
}
public function client()
{
return $this->belongsTo(Notification::class, 'client_id');
}
}
Then you can query like.
User::with(['user']);
or
User::with(['client']);
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.