How to delete hasMany relationship in Laravel without key - laravel

I am trying to delete hasMany relationship but to no avail.
I have three tables: users, user_details, and manufacturers
User hasOne user_details
user_details belongsTo user
manufacturers have many users through user_details
Now when admin deletes manufacturer, it needs to delete all user_details who has that manufacturer_id and all related users.
My tables:
Users:
id, unique_id, first_name, last_name, user_name, email, password, remember_token, created_at, updated_at, deleted_at
User_details
id, user_id, avatar, locale, role_id, manufacturer_id, account_status, hospital_id, phone, city_id, created_at, updated_at, deleted_at
Manufacturers
id, name, status, created_at, updated_at, deleted_at
I am trying to do it like this:
/**
* #return bool|null
* #throws \Exception
*/
public function softDelete()
{
$this->brand_presentations()->delete();
$this->details()->delete();
return parent::delete();
}
And here I have my relations:
public function brand_presentations()
{
return $this->hasMany(Brand_presentations::class, 'manufacturer_id', 'id')->withTrashed();
}
public function details()
{
return $this->hasMany(User_details::class, 'manufacturer_id')->withTrashed();
}
This gives me all the way to the user_details, but I cannot get users. How can I get the users?

If I am understanding you correctly you need to loop through your details to be able to delete the user
/**
* #return bool|null
* #throws \Exception
*/
public function softDelete()
{
$this->brand_presentations()->delete();
$details = $this->details
foreach($details as $detail) {
$user = detail->user
// Delete or access user here
$detail->delete()
}
}

Related

Laravel - User > Roles > Permissions within a Company

I am trying to describe a relationship between a User and a Company. More specific I want the following:
A User has one or Many Roles within a Company.
A Role has one or Many Permissions.
- users (id, name, surname, email, ...)
- permissions (id, name, label, ...)
- roles (id, name, label,...)
- companies (id, name, address, ...)
- permission_role (permission_id, role_id)
- user_role (user_id, role_id)
- company_user (company_id, user_id)
Anyone could help me out?
ER Diagram: https://prnt.sc/q4l614
The pivot_table name will be like user_role_company. Pivot table structure will be like
role_user Table
+---------+-----------+----------+-------------+
| id |user_id | role_id | company_id |
+---------+-----------+----------+-------------+
| 1 | 1 | 2 | 3 |
+---------+-----------+----------+-------------+
One User has one or many company id,
One User has also one or many role id,
One Role has belongs to many user
One Role has belongs to many company.
One Company has belongs to many user.
One Company has belongs to many role.
All of this scenario. you can implements scenario by this -
In User Model
class User extends Authenticatable
{
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function companyies()
{
return $this->belongsToMany(Company::class);
}
}
In Role Model -
class Role extends Model
{
public function users()
{
return $this->belongsToMany(User::class);
}
public function companies()
{
return $this->belongsToMany(Company::class);
}
}
In Company Model -
class Company extends Model
{
public function users()
{
return $this->belongsToMany(User::class);
}
public function roles()
{
return $this->belongsToMany(Role::class);
}
}
Same as for Role and Permission.
You can check the relationship using Laravel tinker.
I Hope it will work for you.
you can read more details from this link : https://laravel.com/docs/6.x/eloquent-relationships#many-to-many

Laravel: Relationships User hasOne Group, Group hasMany User

I want to create a relationship between two tables "users" and "groups", in this relationship, a user belongs to only one group, and the group has multiple users, to solve this, how should i design the table? Need a table "group_user"?
You should use just two tables which names are "users" and "groups". Because one user have only one group. So there is no required to any pivot table.
Tables columns should be like this:
Users: id, name, group_id
Groups: id, name
In the User entity you should do relation like this:
/**
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function group()
{
return $this->belongsTo( Group::class, 'group_id', 'id' );
}
And in the Group entity:
/**
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function users()
{
return $this->hasMany( User::class, 'group_id', 'id' );
}

Laravel relationship within relationship to another table

I have users table, user_roles table and roles table.
My user_roles table:
id, role_id, user_id
My roles table:
id, name, description, created_at, updated_at
My users table:
id, first_name, last_name, user_name, avatar, account_status, email, password, remember_token, created_at, updated_at, deleted_at
Now I am trying to get the logged in user with the role including the role description, but cannot seem to get it working.
In my user model I have this:
public function roles()
{
return $this->hasOne(User_roles::class, 'role_id', 'id');
}
This gives me the User_role but no description. I tried belongsToMany, but this gave me the Roles values and pivot with the User_roles table valus. Can I do it vice versa so I get the User_roles table values and pivot will be the description of the Roles table?
BelongsToMany relationship at the moment:
public function roles()
{
return $this->belongsToMany(Roles::class, 'user_roles', 'id', 'id');
}
Use hasManyThrough relation instead:
https://laravel.com/docs/5.6/eloquent-relationships#has-many-through
This way you can specify the intermediate user_role table
You should try to below solution
In User Model
public function roles()
{
return $this->belongsToMany(Role::class, 'user_roles');
}
In Controller
$user = User::find($user_id);
$roles = $user->roles;
In User Model
public function roles()
{
return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');
}

Eloquent Many to Many select User without certain Roles

So I have User & Role models with many-to-many relationship, I have 3 roles: super, admin and moderator with 4 users let's says: John, Mike, James and Larry.
John is a super, Mike has admin and moderator roles, James is an admin and Larry is a moderator. To displaying users who doesn't have certain roles I created this scope:
public function scopeDoesntHaveRoles($query, $roles = [], $column = 'id') {
return $query->whereDoesntHave('roles')->orWhereHas('roles', function ($q) use ($roles, $column) {
$q->whereNotIn($column, $roles);
});
}
When I call User::doesntHaveRoles([1])->lists('name', 'id') to get users who doesn't have super role, it works and returns:
{"2":"Mike","3":"James","4":"Larry"}
But, when I trying to list users who doesn't have admin role User::doesntHaveRoles([2])->lists('name', 'id'), yes James is not shown there but Mike is appeared while he is actually has admin role:
{"1":"John","2":"Mike","4":"Larry"}
I think it's because Mike is also has moderator role, do you see something wrong in my scope? or do you have other solutions?
Thanks
Edit:
Here is my pivot schema
Schema::create('user_roles', function (Blueprint $table) {
$table->integer('user_id')->unsigned();
$table->integer('role_id')->unsigned();
$table->primary([
'user_id', 'role_id'
]);
});
User model
public function roles()
{
return $this->belongsToMany(Role::class, 'user_roles');
}
Role Model
public function users()
{
return $this->belongsToMany(User::class, 'user_roles');
}
I would use whereNotIn instead of whereDoesntHave.
Given a Role stored in the variable $role you can get all users who don't have that role with:
/* #var Role $role */
User::whereNotIn(function('id', $query) use ($role) {
$query->select('user_id')
->from('user_roles')
->where('role_id', $role->id);
});
The inner query will return all IDs of users who has the given role. Using whereNotIn will return the opposite set of users. The folowing query will be created:
select *
from users
where user_id not in (
select user_id
from user_roles
where role_id = ?
);
Now having a Collection of roles stored in $roles you can get all users who don't have any of that roles with:
/* #var Collection|Role[] $roles */
User::whereNotIn(function('id', $query) use ($roles) {
$query->select('user_id')
->from('user_roles')
->whereIn('role_id', $roles->pluck('id');
});
The inner select will return IDs of all users who has one of the roles in the collection. With whereNotIn you will again get the opposite result. You can also use an array of role-ids instead of $roles->pluck('id').
The builder will create a query like
select *
from users
where user_id not in (
select user_id
from user_roles
where role_id in (?, ?, ..)
);

Laravel hasManyThrough getting through another model

I have this 3 tables. I would like to get the employee name who created the client
I have tried this
class LeadsModel extends Eloquent
public function researcher_name()
{
$user = $this->belongsTo('users','id','user_id');
return $user->getResults()->belongsTo('employees','id','employee_id');
}
But it returns an error:
"message":"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'employees.employee_id' in 'where clause' (SQL: select * from `employees` where `employees`.`employee_id` in (4))"}}
when I switch the id and employee_id, it does not return any relationship for users and employees.
Basically, I need to get the clients with the employee's name who created it.
Assuming relationships:
Client belongsTo User
User belongsTo Employee
simply call this:
$client->user->employee;
Given your schema, here are the relations you need in order to get an Employee related to particular Client (through User):
// Client model
public function user()
{
return $this->belongsTo('User');
}
// User model
public function employee()
{
return $this->belongsTo('Employee');
}
then simply call this:
$client = Client::find($someId);
$client->user; // single user related to the client
$client->user->employee; // single employee related to the user
You might want to check if given relation exists first:
// just an example, don't write it this way ;)
if ($client->user) { // user is not null
if ($client->user->employee) { // employee is not null as well
$client->user->employee->name; // name = field on the employees table
}
}
You need a Has Many Through relation.
Add the relationship in your Employee's model called clients:
public function clients()
{
return $this->hasManyThrough('App\Client', 'App\User');
}
And then you can use it like below:
Employee::first()->clients()->get();

Resources