I have a departments table in db with id,name, and parent.The parent is the id that corresponds to the parent root.Now i have displayed the id(parent id) but i want to show the name of the department that correspond with this id.I have tried the query at the departmentcontroller ,index function but it gives me this error
Illuminate\Database\QueryException
SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'departments' (SQL: select departments.id, departments.parent, departments.name from departments inner join departments on department.id = departments.parent where id = parent)
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($id)
{
$department = Department::with('users')->find($id);
return view('admin.page-users')->with('users', $department->users);
}
public function treeView()
{
$departments = Department::with('childs')->where('parent', 0)->get();
return view('admin.page',compact('departments'));
}
public function index()
{
//$departments = \App\Department::all();
//return view('admin.department')->with('departments', $departments);
return $departments = DB::table('departments')
->join('departments', 'department.id', '=', 'departments.parent')
->select('departments.id','departments.parent','departments.name')->where('id','=','parent')->get();
}
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">×</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 exampleFormControlSelect2" class="col-form-label">Parent ID</label>
<input type="text" class="form-control" placeholder="Choose the department parent id"name="parent" id="recipient-parent">
<select multiple class="form-control" name="parent" id="recipient-parent">
#foreach($departments as $department)
<option>{{ $department->parent }}</option>
#endforeach
</select>
</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 my-4 text-center font-weight-light"> 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>Parent ID</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>
Edit
</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
See the Departments and Employees
</tbody>
</table>
</div>
</div>
</div>
</div>
#endsection
#section('scripts')
#endsection
web.php
<?php
use App\User;
use App\Department;
use App\Events\WebsocketDemoEvent;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
broadcast(new WebsocketDemoEvent('some data'));
return view('welcome');
});
Route::get('/page', function () {
return view('admin.page');
});
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
Route::group(['middleware' => ['auth','admin']], function () {
Route::get('/role-register','Admin\DashboardController#registered');
Route::delete('/role-delete/{id}', 'Admin\DashboardController#registerdelete');//delete user
Route::post('/save-user', 'Admin\DashboardController#store');
Route::get('/department', 'Admin\DepartmentController#index');
Route::post('/save-department', 'Admin\DepartmentController#store');
Route::get('/department-edit/{id}', 'Admin\DepartmentController#edit');//edit department
Route::put('/department-update/{id}', 'Admin\DepartmentController#update');
Route::delete('/department-delete/{id}', 'Admin\DepartmentController#delete');//delete department
Route::get('/page-users/{id}', 'Admin\DepartmentController#usersdep');//show users
});
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
Route::get('/chats', 'ChatsController#index');//chats
Route::get('/messages', 'ChatsController#fetchMessages');//messages
Route::post('/messages', 'ChatsController#sendMessage');//messages
Route::get('/dashboard', 'Admin\DashboardController#dbcheck');//DATABASE
Route::get('/user-edit/{id}', 'HomeController#registeredit');
Route::get('/role-edit/{id}', 'Admin\DashboardController#registeredit');//edit user
Route::put('/role-register-update/{id}', 'Admin\DashboardController#registerupdate');
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
Route::get('store_image', 'StoreImageController#index');
Route::post('store_image/insert_image', 'StoreImageController#insert_image');
Route::get('store_image/fetch_image/{id}', 'StoreImageController#fetch_image');
Route::get('/page',array('as'=>'jquery.treeview','uses'=>'Admin\DepartmentController#treeView'));
Route::get('/pageusers', 'Admin\DepartmentController#usersdep');
Department.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Department extends Model
{
protected $table = 'departments';
protected $fillable = [
'name',
];
protected $primaryKey = 'id';
public function users()
{
// return $this->belongsTo(User::class);
return $this->hasMany(User::class,'department','id');
}
//category has childs
public function childs() {
return $this->hasMany('App\Department','parent','id') ;
/*
childs() method with hasMany relationship.
hasMany relationship in Laravel tell us that they have multiple childs.
Here I am creating relationship based on parent and each category has their parent if parent id is 0 it means it is root category.*/
}
}
create_departments_table
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateDepartmentsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('departments', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->integer('parent');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('departments');
}
}
Alternative answer
Model
A Department model might be associated with one parent. To define this relationship, place a parent method on the model. The parent method should call the hasOne method and return its result:
class Department extends Model
{
protected $fillable = [
'name',
'parent_id',
];
public function parent()
{
return $this->hasOne(Department::class, 'id', 'parent_id');
}
}
Migration
Schema::create('departments', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->unsignedBigInteger('parent_id')->nullable();
$table->timestamps();
$table->foreign('parent_id')->references('id')->on('departments');
});
Usage
Once the relationship has been defined, you can retrieve the parent :
$departments = Department::get();
foreach ($departments as $department) {
if ($parent = $item->parent) {
dd($department->name, $parent->name);
}
else{
dd('This department is a parent')
}
}
You need to pass the correct department id.
public function index()
{
$departments = DB::table('departments')->select('departments.*')->get();
return view('admin.department', compact('departments'));
}
And view:
#foreach($departments as $department)
<tr>
<td>{{ $department->id }}</td>
<td>{{ $department->name }}</td>
#foreach($departments as $parent)
#if( $department->parent === $parent->id )
<td>{{ $department->name }}</td>
#endif
#endforeach
<tr>
#endforeach
Just define a relation in Department model
public function parentDepartment()
{
return $this->belongsTo(self::class, 'parent');
}
and in index method load it
public function index()
{
$departments = Department::with('parentDepartment')->get();
}
Related
Im new to laravel eloquent and i want to know if that loading times are normally with only five entries
Even a simple select all query has ~720 ms specially on edit button that is first photo (modal) the data comes after one second that is noticeable,
Im using Livewire i dont know if affect that too much
The main question that affects extra loading time is how to have access (Aggregate) on child table that counts only the sum of the services, i wrote a simple count on my html {{ $customer->services->count()}} table as you can see runs on each row that is wrong because adds extra loading time.
On php i make something like :
$sql = "SELECT name,vat,id";
$sql .= " ,(select sum(taskcharges) from charges where charges.customers_id=customers.id) as taskcharges_sum";
$sql .= " ,(select sum(payment) from charges where charges.customers_id=customers.id) as payment_sum";
$sql .= " ,(select sum(taskcharges-payment) from charges where charges.customers_id=customers.id) as balance_sum";
$sql .= " ,(select name WHERE customers.id=$id) ";
$sql .= " FROM customers ";
I want to have access from Customers on specific child(services) columns to make functions like max,sum,count the tables are binded on model so i want to avoid extra code of join queries
plus as you can see on sorting the "services" isnt column of Customers table so they dont recognize the column services on customers table, if i had something like "select count(services) as servicecount then i will able to recognize the sorting as new column of the table customers
Above you can see my code:
customers/show.blade.php:
<div class="container">
<p>Sort column:{{$selectedItems}}</p>
<p>Selected Direction:{{$action}}</p>
<!-- Button trigger modal -->
<button wire:click.prevent="addNew" type="button" class="btn btn-primary">
Add New User
</button>
<!-- button triger Modal -->
<div class="modal fade" id="form" 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">Insert</h5>
<button type="button" wire:click.prevent="close"class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
#livewire('customers.form')
</div>
</div>
</div>
</div>
<div class="modal fade" id="delete" tabindex="-1" role="dialog" aria-labelledby="delete" aria-hidden="true" wire:ignore>
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="delete">Delete</h5>
<button type="button" wire:click.prevent="close" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<h3>Do you wish to continue?</h3>
</div>
<div class="modal-footer">
<button type="button" wire:click="close" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button wire:click="delete" class="btn btn-primary">Delete</button>
</div>
</div>
</div>
</div>
<h1 class="text-center">Customers {{count($customers)}}</h1>
<div>
<div class="w-full flex pb-10">
<div class="w-3/3 mx-1">
<input wire:model.debounce.300ms="search" type="text" class="form-control" placeholder="Search users...">
</div>
<div class="row mb-4">
<div class="col form-inline">
Per Page:
<select wire:model="perPage" class="form-control">
<option>5</option>
<option>10</option>
</select>
</div>
</div>
</div>
<table class="table-auto w-full mb-6">
<thead>
<tr>
<th wire:click="sortBy('id')" style="cursor: pointer;" class="px-4 py-2">ID
#include('layouts.partials.sort_icons',['field'=>'id'])
</th>
<th wire:click="sortBy('name')" style="cursor: pointer;" class="px-4 py-2">Name
#include('layouts.partials.sort_icons',['field'=>'id'])</th>
<th wire:click="sortBy('plate')" style="cursor: pointer;" class="px-4 py-2">Plate
#include('layouts.partials.sort_icons',['field'=>'id'])</th>
<th wire:click="sortBy('services')" style="cursor: pointer;" class="px-4 py-2">Services
#include('layouts.partials.sort_icons',['field'=>'services'])</th>
<th class="px-2 py-2">Action</th>
</tr>
</thead>
<tbody>
#foreach($customers as $customer)
<tr>
<td class="border px-4 py-2">{{ $customer->id }}</td>
<td class="border px-4 py-2">{{ $customer->name }}</td>
<td class="border px-4 py-2">{{ $customer->plate }}</td>
<td class="border px-4 py-2">{{ $customer->services->count()}}</td>
<td class="border px-2 py-2">
<button wire:click="selectItem({{$customer->id}},'update')" class="btn btn-info"><i class="fa fa-edit"></I></button></a>
<button wire:click="selectItem({{$customer->id}},'delete')" class="btn btn-danger"><i class="fa fa-trash"></I></button></a>
</td>
</tr>
#endforeach
</tbody>
</table>
<div class="paginate">{{$customers->links()}}</div>
</div>
</div>
customers/Show.php :
<?php
namespace App\Http\Livewire\Customers;
use App\Models\Customer;
use Livewire\Component;
use App\Page;
use Illuminate\Support\Str;
use App\Http\Livewire\Column;
use Livewire\WithPagination;
class Show extends Component
{
public $sortBy= 'name';
public $sortDirection = 'asc';
public $headers;
public $perPage ='5';
public $search;
public $action;
public $selectedItems;
public function sortBy($field){
if ($this->sortDirection =='asc'){
$this ->sortDirection ='desc';
}
else{
$this->sortDirection ='asc';
}
return $this ->sortBy = $field;
}
public function selectItem($itemId,$action){
$this->selectedItems=$itemId;
$this->action=$action;
if ($action=='delete'){
$this->dispatchBrowserEvent('show-deletemodal');
} else{
$this->emit('getcustomerID', $this->selectedItems);
$this->dispatchBrowserEvent('show-modal');
}
}
public function delete(){
Customer::destroy($this->selectedItems);
$this->dispatchBrowserEvent('hide-modal');
}
public function addNew()
{
$this->dispatchBrowserEvent('show-modal');
}
public function close()
{
$this->dispatchBrowserEvent('hide-modal');
}
protected $listeners = [
'deleteconfirmed'=>'$selectedItems',
'refreshParent'=>'$refresh'
];
public function render()
{
$customers = Customer::query()
->search($this->search)
->orderBy($this->sortBy,$this->sortDirection)
->paginate($this->perPage);
return view('livewire.customers.show',['customers'=>$customers
])
->extends('admin.dashboard')
->section('content');
}
}
customers/form.php :
<?php
namespace App\Http\Livewire\Customers;
use App\Models\Customer;
use Livewire\Component;
class Form extends Component
{
public $name ='';
public $plate = '';
public $customerId ;
protected $listeners = [
'getcustomerID'
];
protected function rules() {
return [
'name' => 'required',
'plate' => ['required', 'regex:/[A-Z]{3}\d{4}$/','unique:customers,plate,' . $this->customerId],
];
}
public function updated($propertyName)
{
$this->validateOnly($propertyName);
}
public function getcustomerID($customerId){
$this->customerId=$customerId;
$customer= customer::find ($this->customerId);
$this->name=$customer->name;
$this->plate= $customer->plate;
}
public function save()
{
$this->validate();
$data = [
'name' => $this->name,
'plate' => $this->plate,
];
if ($this->customerId){
customer::find ($this->customerId)->update($data);
session()->flash('message', 'User successfully updated.');
} else{
customer::create($data);
}
$this->emit('refreshParent');
$this->dispatchBrowserEvent('hide-modal');
$this ->ClearVars();
}
public function ClearVars(){
$this->name=null;
$this->plate=null;
}
public function render()
{
return view('livewire.customers.form');
}
}
Models/Customer.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model
{
use HasFactory;
protected $fillable = [
'name',
'plate'
];
public function services()
{
return $this->hasMany(Service::class);
}
public function parts()
{
return $this->hasMany(Part::class, 'customer_id');
}
public function scopeSearch($query , $val){
return $query
->where('name','like','%'.$val.'%')
->Orwhere('plate','like','%'.$val.'%');
}
public function user()
{
return $this->belongsTo(User::class);
}
}
Models/Services.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Service extends Model
{
protected $fillable = [
'service_type',
'km',
];
public function customer()
{
return $this->belongsTo(Customer::class);
}
public function parts()
{
return $this->hasMany(part::class);
}
}
It was so simple.. just added ->withCount('services') above of query
Still have that strange delay
Update :
The problem with slow response was that trying to retrieve data from remote sql server, I change to local and I have less than 100ms!
I have managed to join between 2 tables by using 1 pivot table(I have to), but I cant loop my way to get all of joined result, Bellow are:
Models
App.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class App extends Model
{
protected $table = 'bas_app';
public $timestamps = false;
protected $fillable = ['id','app_name','app_type','description','menu_name','menu_url','menu_parent_id'];
public function roles()
{
return $this->belongsToMany(Role::class,'bas_role_app','app_id','role_id');
}
}
Role.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
//
protected $table = 'bas_role';
protected $fillable = ['name','remark'];
public function users()
{
return $this->belongsToMany('App\User','bas_user_role','role_id','user_id')
->withPivot('id');
}
public function apps()
{
// return $this->belongsToMany(App::class,'bas_role_app','role_id','app_id')
// ->withPivot('id','priv_access','priv_insert','priv_delete',
// 'priv_update','priv_export','priv_print','app_name');
return $this->belongsToMany(App::class,'bas_role_app','role_id','app_id');
}
}
RoleApp.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Pivot;
class RoleApp extends Pivot
{
//
public $timestamps = false;
protected $table = 'bas_role_app';
protected $fillable = ['role_id','app_id','app_name'];
public function b_app() {
return $this->belongsToMany(App::class);
}
public function b_role() {
return $this->belongsToMany(Role::class);
}
}
Controller
RoleAppController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
use Illuminate\Support\Facades\Route;
use App\User;
use App\Role;
use App\App;
use App\ActivityLog;
use App\RoleApp;
use Illuminate\Support\Facades\Input;
use DB;
class RoleAppController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function display(Request $request)
{
$routes = preg_match('/([a-z]*)#([a-z]*)/i', Route::currentRouteAction(), $matches);
$routes = $matches[0];
$action = $matches[2];
if (Auth::check()) {
DB::beginTransaction();
try {
$id = Auth::id();
$profile_data = User::find($id);
$RoleApp = Role::all();
//$RoleApp->apps;
// dd($RoleApp);
ActivityLog::create([
'inserted_date' => Carbon::now()->TimeZone('asia/jakarta'),
'username' => $profile_data->username,
'application' => $routes,
'creator' => "System",
'ip_user' => $request->ip(),
'action' => $action,
'description' => "admin is looking at the role and application management",
'user_agent' => $request->server('HTTP_USER_AGENT')
]);
DB::commit();
} catch (\Exception $ex) {
DB::rollback();
return response()->json(['error' => $ex->getMessage()], 500);
}
// return view('RoleApp', ['RoleApp' => $RoleApp]);
return view('RoleApp', ['RoleApp' => $RoleApp]);
} else {
return view("login");
}
}
}
View
RoleApp.blade.php
#extends('layouts.master')
#section('title','Display-RoleApp')
#section('content')
<div class="container mt-5">
<div class="row">
<div class="col-12">
#if($errors->any())
<div class="alert alert-danger alert-dismissible fade show" role="alert">
{{ implode(', ', $errors->all(':message')) }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
#endif
<div class="float-right mb-5">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModalCenter">
Insert Role App
</button>
</div>
<!-- Modal -->
<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle">Insert User</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form action="/roleapp/create" method="POST">
{{ csrf_field() }}
<div class="form-group">
<label for="role_name">role name:</label>
<input type="text" class="form-control" name="role_name">
</div>
<div class="form-group">
<label for="app_name">app name:</label>
<input type="text" class="form-control" name="app_name">
</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">Submit</button>
</div>
</form>
</div>
</div>
</div>
<div class="table-responsive m-b-40">
<table id="roleapp-table" class="table table-striped">
<thead>
<tr>
<th scope="col">Role Name</th>
<th scope="col">App Name</th>
<th scope="col" class="text-center">Action</th>
<th scope="col" class="text-center">Action</th>
</tr>
</thead>
<tbody id="dynamic-row">
#foreach ($RoleApp->apps as $rp)
<tr>
<td>{{$RoleApp->name}}</td>
<td>{{$rp->app_name}}</td>
<td class="text-center">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal_ubah_{{$rp->id}}">Edit</button>
</td>
<td class="text-center">
<button type="button" class="btn btn-danger" data-toggle="modal" data-target="#modal_hapus_{{$rp->id}}">Hapus</button>
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
</div>
<script type="text/javascript">
var row = 0;
$(document).ready(function() {
$('#user-table').DataTable({
select: true,
retrieve: true,
"order": [
[0, "desc"]
],
"lengthMenu": [
[20, 50, 100, 500, 1000, -1],
[20, 50, 100, 500, 1000, "All"]
],
"language": {
"paginate": {
"next": ">",
"previous": "<"
}
}
});
});
$('#user-table thead tr').clone(true).appendTo('#user-table thead');
$('#user-table thead tr:eq(1) th').each(function(i) {
if (row < 7) {
var title = $(this).text();
$(this).html('<input type="text" placeholder="Search ' + title + '" />');
} else {
$(this).html('');
}
row++;
$('input', this).on('keyup change', function() {
if (table.column(i).search() !== this.value) {
table
.column(i)
.search(this.value)
.draw();
}
});
});
</script>
#endsection
Any suggestion? I have tried various way and its still not working. I suspect that something is wrong in
$RoleApp = Role::all();
or
#foreach ($RoleApp->apps as $rp)
<tr>
<td>{{$RoleApp->name}}</td>
<td>{{$rp->app_name}}</td>
<td class="text-center">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal_ubah_{{$rp->id}}">Edit</button>
</td>
<td class="text-center">
<button type="button" class="btn btn-danger" data-toggle="modal" data-target="#modal_hapus_{{$rp->id}}">Hapus</button>
</td>
</tr>
#endforeach
if I try it with $RoleApp = Role::find(2); it will still work, but when i use get or all, it wont work.
without eager loading.
$roles = Role::all();
with eager loading
$roles = Role::with('apps')->get();
$roles is a collection of model instances of Role Model. You can't access a property or relation of a model, on a collection. That is the reason it works when you use find(given model instance), and doesn't work for all or get(give collection).
You need to iterate over the collection and then access the relation like this.
foreach($roles as $role){
// name of each role.
$role->name;
foreach($role->apps as $app){
// name of each app associated with the $role.
$app->name;
}
}
I have a create form for creating courses, I have assigned users to these courses however for some reason it is not working anymore. I have been through my code umpteen times and I can't find anything that has changed - so i have come here for help.
To give some context below is my index.blade.php. As you can see I have previously assigned users to a course.
Create.blade.php;
#extends('layouts.app')
#section('content')
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Create Course</div>
<div class="card-body">
<form method="POST" action="{{ route('admin.courses.store') }}" enctype="multipart/form-data">
#csrf
<div class="form-group">
<label class="required" for="name">Course Title</label>
<input class="form-control" type="text" name="title" id="id" value="{{ old('title', '') }}" required>
#if($errors->has('name'))
<div class="invalid-feedback">
{{ $errors->first('name') }}
</div>
#endif
</div>
<div class="form-group">
#can('create_courses')
{!! Form::label('Instructor', 'Instructor', ['class' => 'control-label']) !!}
{!! Form::select('Instructor[]', $instructors, Request::get('Instructor'), ['class' => 'form-control select2', 'multiple' => 'multiple']) !!}
#if($errors->has('Instructor'))
{{ $errors->first('Instructor') }}
#endif
#endcan
</div>
<div class="form-group">
<button class="btn btn-danger" type="submit">
Save
</button>
</div>
</div>
</form>
</div>
</div>
#endsection
Index.blade.php;
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-10">
<p>
#can('create_courses')
<button type="button" class="btn btn-success">Create Course</button>
#endcan('create_courses')
</p>
<div class="card">
<div class="card-header">Courses</div>
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Course Title</th>
<th>Instructor</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
#foreach($course as $course)
<tr>
<th scope="row">{{ $course->id }}</th>
<td>{{ $course->title}}</td>
<td>{{ implode (', ', $course->instructors()->pluck('name')->toArray()) }}</td>
<td>
#can('edit_courses')
<a class="btn btn-xs btn-secondary" href="{{ route('admin.modules.index', $course->id) }}">
Modules
</a>
#endcan
</td>
<td>
#can('edit_courses')
<a class="btn btn-xs btn-primary" href="{{ route('admin.courses.edit', $course->id) }}">
Edit
</a>
#endcan
</td>
<td>
#can('delete_courses')
<form action="{{ route('admin.courses.destroy', $course->id) }}" method="POST" onsubmit="return confirm('Confirm delete?');" style="display: inline-block;">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="submit" class="btn btn-xs btn-danger" value="Delete">
</form>
#endcan
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- <div class="col-md-2 col-lg-2">
<div class="list-unstyled">
Courses
Modules
</div>
</div> -->
</div>
</div>
#endsection
CoursesController.php;
<?php
namespace App\Http\Controllers\Admin;
use Gate;
use App\User;
use App\Course;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Input;
class CoursesController extends Controller
{
public function __construct()
{
//calling auth middleware to check whether user is logged in, if no logged in user they will be redirected to login page
$this->middleware('auth');
}
public function index()
{
if(Gate::denies('manage_courses')){
return redirect(route('home'));
}
$courses = Course::all();
return view('admin.course.index')->with('course', $courses); //pass data down to view
}
public function create()
{
if(Gate::denies('create_courses')){
return redirect(route('home'));
}
$instructors = User::whereHas('role', function ($query) {
$query->where('role_id', 2); })->get()->pluck('name'); //defining instructor variable to call in create.blade.php. Followed by specifying that only users with role_id:2 can be viewed in the select form by looping through the pivot table to check each role_id
return view('admin.course.create', compact('instructors')); //passing instructor to view
}
public function store(Request $request)
{
$course = Course::create($request->all()); //request all the data fields to store in DB
$course->instructors()->sync($request->input('instructors', [])); //input method retrieves all of the input values as an array
if($course->save()){
$request->session()->flash('success', 'The course ' . $course->title . ' has been created successfully.');
}else{
$request->session()->flash('error', 'There was an error creating the course');
}
return redirect()->route ('admin.courses.index');
}
public function destroy(Course $course)
{
if(Gate::denies('delete_courses'))
{
return redirect (route('admin.course.index'));
}
$course->delete();
return redirect()->route('admin.courses.index');
}
public function edit(Course $course)
{
if(Gate::denies('edit_courses'))
{
return redirect (route('admin.courses.index'));
}
$instructors = User::whereHas('role', function ($query) {
$query->where('role_id', 2); })->get()->pluck('name');
return view('admin.course.edit')->with([
'course' => $course
]);
}
public function update(Request $request, Course $course)
{
$course->update($request->all());
if ($course->save()){
$request->session()->flash('success', $course->title . ' has been updated successfully.');
}else{
$request->session()->flash('error', 'There was an error updating ' . $course->title);
}
return redirect()->route('admin.courses.index');
}
public function show(Course $course)
{
return view('admin.course.show', compact('course'));
}
}
I am new to laravel so I would appreciate any help.
I have created a migration called 'create_modules_table' see code below.
public function up()
{
Schema::create('modules', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('course_id')->nullable();
$table->foreign('course_id')->references('id')->on('courses');
$table->string('title');
$table->timestamps();
});
}
I have added a FK 'course_id'. Without 'nullable' i faced an error relating to 'course_id' not having a default value. So i added 'nullable'. However now it is throwing me further problems, when i create a new module and select the course to attach to the module, the field in the DB is null (despite selecting an existing course from my form). I have added an image for context. Can anyone tell me where i am going wrong? I'm not sure how to go about fixing this.
Module.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Module extends Model
{
protected $fillable = [
'title', 'course_id', 'created_at', 'updated_at',
];
public function course()
{
return $this->belongsTo(Course::class, 'course_id');
}
}
ModulesController;
<?php
namespace App\Http\Controllers\Admin;
use App\Module;
use App\Course;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class ModulesController extends Controller
{
public function index(Request $request)
{
$modules = new module();
if ($request->input('course_id')) {
$modules = $modules->where('course_id', $request->input('course_id'));
}
$modules = $modules->all();
return view('admin.module.index', compact('modules'));
}
public function create()
{
$courses = Course::all()->pluck('title', 'id');
return view('admin.module.create', compact('courses'));
}
public function store(Request $request)
{
$module = Module::create($request->all());
return redirect()->route('admin.modules.index', ['course_id' => $request->id]); //redirects to correct route by adding course_id in parameter
}
}
create.blade.php;
#extends('layouts.app')
#section('content')
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Create Module</div>
<div class="card-body">
<form method="POST" action="{{ route('admin.modules.store') }}" enctype="multipart/form-data">
#csrf
<div class="form-group">
<label class="required" for="name">Module Title</label>
<input class="form-control" type="text" name="title" id="id" required>
#if($errors->has('name'))
<div class="invalid-feedback">
{{ $errors->first('name') }}
</div>
#endif
</div>
<div class="form-group">
{!! Form::label('Courses', 'Course', ['class' => 'control-label']) !!}
{!! Form::select('Course[]', $courses, Request::get('Course'), ['class' => 'form-control select2', 'multiple' => 'multiple']) !!}
</div>
<div class="form-group">
<button class="btn btn-danger" type="submit">
Save
</button>
</div>
</div>
</form>
</div>
</div>
#endsection
index.blade.php;
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<p>
<button type="button" class="btn btn-success">Create Module</button>
</p>
<div class="card">
<div class="card-header">Modules</div>
<div class="card-body">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Module Title</th>
<th>Course Title</th>
<th>Instructor</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
#foreach($modules as $key => $module)
<tr>
<th scope="row">{{ $module->id }}</th>
<td>{{ $module->title }}</td>
<td>{{ $module->course->title ?? ''}}</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
#endsection
I would like to add there is no error, the DB is simply not displaying an input.. for some reason. Any help is kindly appreciated.
In your form there is no field named course_id, instead you've a field with name Course[] which is a multi-select, so in your store method when you are using Module::create($request->all()); there is no field matching in your $fillable array in the Module model, so you need to map fields manually and also, since you are using an array (because multi-select produces array), you need to use single element from the array to create a relation.
So, one easy approach could be ():
Module::create([
'title' => $request->input('title'),
'course_id' => reset($request->input('course')) // get the first item from array
]);
I think your are missing something, you should not use a multi-select for a foreign key unless you've a many-to-many relation and in that case you'll create/attach multiple related entries in a pivot table.
when i search it will show error
ErrorException (E_ERROR) Undefined variable: group (View: C:\xampp\htdocs\ff\Laravel-Webboard-Workshop-master\resources\views\topic\index.blade.php) Previous exceptions Undefined variable: group (0)
in topic page at line of route('topic.create', $group->id) that is code about button new topic
view/topic/index.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-12">
#if (! Auth::guest())
<form action="/search_topic" method="get">
<button type="submit" class="btn btn-primary" style="float:right;">Search</button>
<a style="float:right;">
<input type="search" name="search" class="form-control" >
</a>
</form>
<br><br>
<div>
<a href="{{ url('/') }}" style="text-align:left;">
<button type="button" class="btn btn-default">
<span aria-hidden="true"></span>
Back to Home
</button>
</a>
<a href="{{ route('topic.create', $group->id) }}" style="float:right;"> <!--error-->
<button type="button" class="btn btn-primary">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
New Topic
</button>
</a>
</div>
<br />
#endif
<div class="panel panel-default">
<div class="panel-heading" style="font-size: 18px;">
Group: {{ $group->title }}
</div>
<div class="panel-body">
<table class="table table-striped table-linkable table-hover">
<thead>
<tr>
<th class="text-center">Topic</th>
<th class="text-center">Posted By</th>
<th class="text-center">Posted At</th>
#if (! Auth::guest())
<th>Edit</th>
<th>Delete</th>
#endif
</tr>
</thead>
<tbody>
#foreach($topics as $topic)
<tr onclick="document.location.href = '{{ action('TopicController#show', $topic->id) }}'">
<td>{{ $topic->title }}</td>
<td class="text-center">{{ $topic->user['name'] }}</td>
<td class="text-center">{{ $topic->created_at->diffForHumans() }}</td>
#if (! Auth::guest())
<td>
#if (Auth::user()->id == $topic->user_id)
Edit
#endif
</td>
<td>
#if (Auth::user()->id == $topic->user_id)
<form method="post" class="delete_form" action="{{action('TopicController#destroy', $topic->id)}}">
{{csrf_field()}}
<input type="hidden" name="_method" value="DELETE" />
<button type="submit" class="btn btn-danger" onclick="return myFunction();">Delete</button>
<script>
function myFunction() {
if(!confirm("Are You Sure to Delete"))
event.preventDefault();
}
</script>
</form>
#endif
</td>
#endif
</tr>
#endforeach
</tbody>
</table>
<div class="text-center">
{!! $topics->links(); !!}
</div>
</div>
</div>
</div>
</div>
</div>
#endsection
model Topic.php
<?php
namespace App;
use App\Group;
use App\Topic;
use Illuminate\Database\Eloquent\Model;
class Topic extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'title', 'body'
];
/**
* Get the Comments of a given topic.
*
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function comments()
{
return $this->hasMany('App\Comment');
}
/**
* Get a user of a given topic
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('App\User');
}
public function group()
{
return $this->belongsTo('App\Group');
}
}
TopicController.php
<?php
namespace App\Http\Controllers;
use App\Comment;
use App\Topic;
use App\Group;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
class TopicController extends Controller
{
public function search(Request $request)
{
$search = $request->get('search');
//$groups = DB::table('groups')->where('title', 'like', '%'.$search.'%')->paginate(5);
$topics = Topic::with('user')->where('title', 'like', '%'.$search.'%')->paginate(5);
return view('topic.index', ['topics' => $topics] );
}
}
How should i do to fix this bug for search in my topic page??