2

I have a Laravel project with two tables in db,departments and users.The admin can delete departments and users.A user has one department and a department has many users.I want to check in the delete function that if a department has a user he cant be deleted.I have write this delete department function but it gives me this error ErrorException Trying to get property 'users' of non-object create_users_table

    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            //$table->text('avatar');
            $table->string('name');
            $table->string('lastname');
            $table->string('phone');
            $table->string('jobtitle');
            $table->integer('department');
            $table->timestamps();
            $table->string('usertype')->nullable();
            $table->string('email');
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();

        });
    }

create_departments_table

public function up()
    {
        Schema::create('departments', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->integer('parent');
            $table->timestamps();
        });
    }

DepartmentController.php

<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use  App\Department;
use  App\User;
use Illuminate\Support\Facades\DB;

class DepartmentController extends Controller
{  

     public function usersdep(){
      //THIS IS THE ADDED CODE   

        $users =  DB::table('users')
      ->join('departments', 'users.department', '=', 'departments.id')
      ->select('users.id','users.lastname','users.name as username','departments.name')->get();
      return view('admin.pageusers')->with('users', $users);
      //print_r($users);exit;
    //  foreach($users as $user)
     // {      
         // return $user;      
        //dd($department->name);
       //dd($user->username);    

    //  } 
      //ADDED CODE
     } 



  public function treeView(){       
    $departments =  Department::where('parent', '=', 0)->get();   
    $tree='<ul id="browser" class="filetree"><li class="tree-view"></li>';
    foreach ($departments as $department) {     
      $tree .='<li class="tree-view closed"<a class="tree-name">'.$department->name.'</a>'; //first department
      if(count($department->childs)) {
        $tree .=$this->childView($department);// if this department has children               
      }
    }
    $tree .='</ul>';
    //return $tree;
    return view('admin.page',compact('tree'));
  }


  public function childView($department){                 
    $html ='<ul>';

    foreach ($department->childs as $arr){

      if(count($arr->childs))
      {
        $html .='<li class="tree-view closed"><a class="tree-name">'.$arr->name.'</a>';                  
        $html.= $this->childView($arr);
      }
      else
      {
        $html .='<li class="tree-view" ><a class="tree-name">'.$arr->name.'</a></a>';                                 
        $html .="</li>";
      }                                                
    }            
    $html .="</ul>";
    return $html;
  } 


 /* public function usersdep(){       
    $users =  DB::table('users')
    ->join('departments', 'users.department', '=', 'departments.id')
    ->select('users.id','users.lastname','users.name as username','departments.name')->get();  
    $tree='<ul id="browser" class="filetree"><li class="tree-view"></li>';
    foreach ($users as $user) {     
      $tree .='<li class="tree-view closed"<a class="tree-name">'.$user->name.'</a>'; //first department
      if(count($user->childs)) {
        $tree .=$this->childView($user);// if this department has children               
      }
    }
    $tree .='</ul>';
    //return $tree;
    return view('admin.pageusers',compact('tree'));
  }*/




  public function index()
  {
    $departments = \App\Department::all();

    return view('admin.department')->with('departments', $departments);
  }

  public function store(Request $request) 
  {
    $departments =  new Department;
    $departments->id = $request->input('id');
    $departments->name = $request->input('name');
    $departments->parent = $request->input('parent');
    $departments->save();
    return redirect('department')->with('status','Data added');
  }

  public function edit($id)
  {
    $departments = Department::findOrFail($id);
    return view('admin.department-edit')->with('departments',$departments);

  }

  public function update(Request $request,$id)
  {
    $departments = Department::find($id);
    $departments->id = $request->input('id');
    $departments->name = $request->input('name');
    $departments->parent = $request->input('parent');
    $departments->update();
    return redirect('/department')->with('status','Data updated');

  }

  public function delete($id)
  {
     $users = User::all();
     $departments = Department::findOrFail($id);
    $hasUser = false;
    foreach ($departments as $department) {
      if ($department->users->withTrashed()->count()) {

          $hasUser = true;
          break;
      }
      if ($hasUser)
       {
        $departments->delete();
        //$this->delete();
       } 
      else
       {
      $departments->forceDelete();
       // $this->forceDelete();
       }
  }
    //$departments->delete();
    return redirect('/department')->with('status','Data deleted');
  }










  //menyre tjt
  /*
  function CategoryTree($output=null, $parent=0, $indent=null){

  $departments =  DB::table('departments')->get();

  // show the departments one by one

  //return $r;
  foreach($departments as $dep){
  $output = '<ul>';
  if($dep->parent== 0){
  $output .= '<li>'.$dep->name.'</li>';
} else {

}
}
while($c = $r->fetch(PDO::FETCH_ASSOC)){
return '12';
$output .= '<option value=' . $c['id'] . '>' . $indent . $c['name'] . "</option>";
if($c['id'] != $parent){
// in case the current departments's id is different that $parent
// we call our function again with new parameters
CategoryTree($output, $c['id'], $indent . "&nbsp;&nbsp;");
}
}
// return the list of departments
return $output;
}
*/



}

User.php

    public function department()
    {
        return $this->belongsTo(Department::class);
    }

Department.php

public function users()
{
    return $this->belongsTo(User::class);
}

department.blade.php

@extends ('layouts.master')

@section('title')
Department Management | Admin
@endsection
@section('content')

<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">New department</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
        @if (session('status'))
        <div class="alert alert-success" role="alert">
          {{ session('status') }}
        </div>
        @endif
      </div>
      <form action="/save-department" method="POST">
        {{   csrf_field() }}
        <div class="modal-body">         
          <div class="form-group">
            <label for="recipient-name" class="col-form-label">Name</label>
            <input type="text" class="form-control" name="name" id="recipient-name">
          </div>
          <div class="form-group">
            <label for="recipient-name" class="col-form-label">ID</label>
            <input type="text" class="form-control" name="id" id="recipient-id">
          </div> 
          <div class="form-group">
            <label for="recipient-name" class="col-form-label">Parent ID</label>
            <input type="text" class="form-control" name="parent" id="recipient-parent">
          </div>          
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
          <button type="submit" class="btn btn-primary">Save</button>
        </div>
      </form>
    </div>
  </div>
</div>
<div class="row">
  <div class="col-md-12">
    <div class="card">
      @if (session('status'))
      <div class="alert alert-success" role="alert">
        {{ session('status') }}
      </div>
      @endif
      <div class="card-header">
        <h4 class="card-title"> Department Management </h4>
      </div>
      <div class="card-body">
        <div class="table-responsive">
          <table class="table">
            <thead class=" text-primary">
              <th>Department</th>
              <button type="button" class="btn btn-primary float-right" data-toggle="modal" data-target="#exampleModal" >Add</button>              
              <thead class=" text-primary">
                <th>ID</th>
                <th>Name</th>
                <th>PID</th>
                <th>Edit</th>
                <th>Delete</th>
              </thead>
            </thead>
            <tbody>
              @foreach($departments as $department)
              <tr>
                <td>{{ $department->id }}</td>  
                <td>{{ $department->name }}</td>  
                <td>{{ $department->parent }}</td> 
                <td>
                  <a href="{{  url('department-edit/'.$department->id) }}" class="btn btn-success">Edit</a>
                </td>       
                <td>
                  <form action="{{  url('department-delete/'.$department->id) }}" method="POST">
                    {{ csrf_field() }}
                    {{ method_field('DELETE') }}
                    <button type="submit"  class="btn btn-danger">Delete</button>
                  </form>                           
                </td>               
              </tr> 
              @endforeach  
              <a href="{{  url('/page') }}" class="btn btn-success">See the Departments and Employees</a>                                                     
            </tbody>           
          </table>  
        </div>
      </div>
    </div>
  </div>


  @endsection


  @section('scripts')


  @endsection
```[![enter image description here][1]][1]


  [1]: https://i.stack.imgur.com/zbJ0u.jpg
Coder
  • 131
  • 2
  • 11

3 Answers3

1

You need to change your relationship in the department model.

 public function users()
    {
        return $this->hasMany(Users::class,'department_id','id');
    }

Since a department has many users then in your Users table you must have a column which stored the department id. Probably named department_id and it's the foreign key to departments table.

Having done than you can twist your query like:

     $departments = Department::with('users')
->where('id','=',$id)
->firstOrFail(); //users is the name of your function in departments model

This will have a nested object with key users.

So you can check then:

if($departments->users->isEmpty()){
//Delete
}
pr1nc3
  • 8,108
  • 3
  • 23
  • 36
  • i tried this but it gives me this error: SQLSTATE[42S22]: Column not found: 1054 Unknown column '6' in 'field list' (SQL: select `6` from `departments` limit 1) – Coder Feb 21 '20 at 12:35
  • in my users table it has "department" and i changed your answer from departmend id to department but i get this even after changing it – Coder Feb 21 '20 at 12:41
  • @klearn check my new query. That one will work – pr1nc3 Feb 21 '20 at 12:43
  • can this happen if i dont have the migration right with the foreign key ,i added the migration at the question – Coder Feb 21 '20 at 13:35
  • What is the output of $departments after using my query? – pr1nc3 Feb 21 '20 at 13:48
  • SQLSTATE[42S22]: Column not found: 1054 Unknown column 'users.department_id' in 'where clause' (SQL: select * from `users` where `users`.`department_id` in (7)) – Coder Feb 21 '20 at 13:52
  • Once again, put your column (department) in the relationship model OR build your migration replacing department with department_id. – pr1nc3 Feb 21 '20 at 13:54
  • this department should be at the ->where('department','=',$id) ? – Coder Feb 21 '20 at 13:56
  • No, this is the id of the departments table. Not the foreign key in the users table. This is correct as is. – pr1nc3 Feb 21 '20 at 13:58
  • bcause i cant find any department_id in my files i had this before when i created the project and then i changed it to department – Coder Feb 21 '20 at 14:03
  • Ok in the relationship, the hasMany, in the model, change department_id to department and you should be fine, and use the query i have in my answer. – pr1nc3 Feb 21 '20 at 14:06
  • yes after that it was giving me error about undefined variable department ,cause at the controller i wrote it by mistake ,i changed it to departments and then it was okay thank you very much – Coder Feb 21 '20 at 14:10
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/208258/discussion-between-k-learn-and-pr1nc3). – Coder Feb 21 '20 at 14:34
1

In your Department model: Replace this

public function users()
{
    return $this->belongsTo(User::class);
}

with

public function users()
{
    return $this->hasMany(User::class);
}


Change your delete() method in DepartmentController to this:

public function delete($id)
{
    $department = Department::findOrFail($id);
    if($department->users()->exists()){
        return redirect()->back()->with('Error', 'Department is not empty!');
    }

    $department->delete();

    return redirect('/department')->with('status','Data deleted');
}
Qumber
  • 13,130
  • 4
  • 18
  • 33
  • give me this error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'users.department_id' in 'where clause' (SQL: select exists(select * from `users` where `users`.`department_id` = 6 and `users`.`department_id` is not null) as `exists`) – Coder Feb 21 '20 at 12:39
  • That is because you need a foreign key to point your users table to department table. i.e. `department_id` column should be present in `users` table and it should have value of it's department's `id` from the `departments` table. – Qumber Feb 21 '20 at 12:44
  • i added the migrations at the question do you mean i should add foreign key at migrations file? – Coder Feb 21 '20 at 13:30
  • Simply use this to add a column called `department_id` in your migration: `$table->unsignedBigInteger('department_id');` Here is the doc for the same: https://laravel.com/docs/5.8/migrations#foreign-key-constraints – Qumber Feb 21 '20 at 13:43
  • the problem is that i have some data and php artisan migrate:refresh fresh it deletes them isnt any other way without changing the migrations? – Coder Feb 21 '20 at 13:45
  • You can add one more migration using artisan: `php artisan make:migration add_department_id_column_to_users_table --table=users`. Do the thing in the newly created file, then, run: `php artisan migrate` – Qumber Feb 21 '20 at 13:47
  • i added this return $this->hasMany(User::class,'department','id'); as the above answer but your answer also helped me thank you very very much – Coder Feb 21 '20 at 14:16
  • 1
    That means 'department' was the foreign key. Glad it worked out for you. You are very welcome. – Qumber Feb 21 '20 at 14:22
  • 1
    yes that was ,thank you ,you helped me a lot – Coder Feb 21 '20 at 14:25
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/208259/discussion-between-k-learn-and-qumber-rizvi). – Coder Feb 21 '20 at 14:54
1

First: you should replace belongsTo() relation with hasMany() relation in Department class.

Second: $departments = Department::findOrFail($id); returns model, not collection of models, you shouldn't iterate through it.

Third: I suppose withTrashed() is method of query builder, not a method of collection. $department->users returns collection, $department->users() returns query builder. You should use $department->users()->withTrashed()

Finally:

Relation of Department class

public function users()
{
    return $this->hasMany(User::class);
}

Controller method:

public function delete($id)
{
    $department = Department::findOrFail($id);

    if($deparment->users()->withTrashed()->exists()){
        $department->delete();
    } else {
        $department->forceDelete();
    }

    return redirect('/department')->with('status','Data deleted');
}
IndianCoding
  • 2,602
  • 1
  • 6
  • 12