Got a ManyOnMany system (3 tables, projects, users, project_user)
Many users can work on a project, and a user can have many projects.
When checkbox = checked it sends the database to the pivot table.
Now I'm facing the problem that everytime I click the project/user id will get send to the project_user table.
And I need to have the checkbox already checked when the user is actually added to the project.
So how I see it: the form::checkbox has a third function checked or not checked, and with an if/else statement in my controller.edit I will have a validation somehow. Please help me!
Blade:
#foreach($users as $user)
<tr>
<td>
{{$user->firstname}} {{$user->middlename}} {{$user->lastname}}
</td>
<td>
{!! Form::checkbox('contribute['.$user->id.']', '1', $checkifinproject) !!}
</td>
</tr>
#endforeach
Controller:
public function edit($id, Project $project)
{
$users = User::all();
$project = $this->project->find($id);
if ($users == $project)
{
$checkifinproject = 'checked';
}
else {
}
return view('project.edit', ['project' => $project, 'id' => 'edit', 'project_id' => $id], compact('users'));
}
public function update(CreateProjectRequest $request)
{
if($request->get('contribute'))
{
foreach($request->get('contribute') as $k => $contribute)
{
if($contribute == 1)
{
$project = $this->project->find($request->project_id);
$project->users()->attach($k);
}
}
}
$project = $this->project->find($request->project_id);
$project->fill($request->input())->save();
return redirect('project');
}
Model:
User
public function projects()
{
return $this->belongsToMany('App\Project', 'project_user', 'user_id', 'project_id');
}
Project
public function users()
{
return $this->belongsToMany('App\User', 'project_user', 'project_id', 'user_id');
}
I think the issue is you are comparing two things that will never be the same and trying to determine if that user belongs to the project. A better thing to do would be to query all the users with their projects and as you loop through the users, check to see that the project you are modifying is one of the projects the user belongs to.
That can be done like this...
Controller
public function edit($id, Project $project)
{
$users = User::with('projects')->get();
$project = $this->project->find($id);
return view('projects.edit', ['users' => $users, 'project' => $project]);
}
View
#foreach($users as $user)
<tr>
<td>
{{$user->firstname}} {{$user->middlename}} {{$user->lastname}}
</td>
<td>
{!! Form::checkbox('contribute['.$user->id.']', '1', $user->projects->contains('id', $project->id)) !!}
</td>
</tr>
#endforeach
Related
I want to send my data from controller to xedit.blade.php, but I get the same error:
Undefined variable: users
in controller:
public function index3()
{
$users=User::all();
return view('xedit')->with('users' => $users);
}
Routes:
Route::get('/index3','Admin\UsersController#index3');
and I want to use $users in blade.Maybe there is a Route problem?
in your index method
public funtion index()
{
$users=User::all();
return view('xedit', compact('users'));
}
in your view add $users
<table>
#foreach ($users as $item)
<tr>
<td>{{ $item->id }}</td>
<td>{{ $item->name }}</td>
</tr>
#endforeach
</table>
Your code logic is perfect, I guess you have to use proper naming with your routes because of Laravel Standard.
Route::get('/admin/show','Admin\UsersController#index')-name('admin.show');
public function index()
{
$users = User::all();
return view('xedit')->with('users' => $users);
}
In view, blade use a professional approach like below
#isset($users)
... loop ...
#endisset()
check record before sending to view by using dump and die function dd($users);
Want to comment but doesn't have 50 reputation
Replace ('users' => $users); this with (['users' => $users]); as you are using =>
So I'm printing user complaints in table where I'm also printing a Delete button with every row. When I click that delete button, I want to delete that specific complaint from the table. I'm not using Resource Controller for this but a Basic Controller. Now, this is my code:
ViewComplaint.blade.php (Complaints Table with Delete Button):
<table id="cTable" class="table table-striped table-bordered">
<thead>
<tr>
<th>Student Name</th>
<th>Complaint Title</th>
<th>Complaint Description</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#foreach($complaints as $complaint)
<tr>
<td>{{ $complaint->name }}</td>
<td>{{ $complaint->cname }}</td>
<td>{{ $complaint->cbody }}</td>
<td class="btn-group">
{!! Form::open(array('route'=>['complaint.destroy',$complaint->id],'method'=>'DELETE')) !!}
{!! Form::submit('Delete',['type'=>'submit','style'=>'border-radius: 0px;','class'=>'btn btn-danger btn-sm',$complaint->id]) !!}
{!! Form::close() !!}
</td>
</tr>
#endforeach
</tbody>
</table>
Web.php (Routes):
Route::get('/complaint/create','ComplaintController#create')->name('complaint.create');
Route::post('/complaint','ComplaintController#store')->name('complaint.store');
Route::get('/complaint','ComplaintController#index')->name('complaint.index');
Route::delete('/complaint/{$complaint->id}','ComplaintController#destroy')->name('complaint.destroy');
ComplaintController.php (Basic Controller):
class ComplaintController extends Controller
{
public function index() {
$complaints = Complaint::all();
return view('viewcomplaint',compact('complaints'));
}
public function create(User $user) {
$user = User::all();
$user->name = Auth::user()->name;
return view('createcomplaint',compact('user'));
}
public function store(Request $request, Complaint $complaint, User $user) {
$user = User::find($user);
$complaint->name = Auth::user()->name;
$complaint->cname = $request->input('cname');
$complaint->cbody = $request->input('cbody');
//update whichever fields you need to be updated
$complaint->save();
return redirect()->route('home.index');
}
public function destroy(Complaint $complaint,$id)
{
$complaint = Complaint::findOrFail($complaint->id);
$complaint->delete();
return redirect()->route('complaint.index');
}
}
Now when I click the Delete button on the table, it just gives me "404 | Not Found" error. What am I doing wrong here? I would really appreciate some help.
remove the $id from the route
Route::delete('/complain/{id}','ComplaintController#destroy')->name('complaint.destroy');
public function destroy($id) {
}
The route parameter is just a name; you are saying this particular route segment is dynamic and I want the parameter named complaint:
Route::delete('complaint/{complaint}', 'ComplaintController#destroy')->name('complaint.destroy');
Then you can adjust your destroy method to take the parameter complaint typehinted as Complaint $complaint to get the implicit binding:
public function destroy(Complaint $complaint)
{
$complaint->delete();
return redirect()->route('complaint.index');
}
Seems to me you're defining your route wrong. Change your route to:
Route::delete('/complaint/{id}','ComplaintController#destroy')->name('complaint.destroy');
You don't need an array() in your form opening, so hange your form opening to this:
{!! Form::open(['method' => 'DELETE', 'route' => ['complaint.destroy',$complaint->id]]) !!}
And remove the $complaint->id from your submit button, you don't need it there.
All you have to do now inside your function is to find Complaint that has the id you passed in your form:
public function destroy($id)
{
$complaint = Complaint::findOrFail($id);
$complaint->delete();
return redirect()->route('complaint.index');
}
Let me know if you stumble on any errors.
I'm getting started on mastering Laravel. I'm trying to create a system where the superuser can edit the roles of all the users. It has been going well until now.
My front end looks like this:
#section('content')
<table>
<thead>
<th>Voornaam</th>
<th>Achternaam</th>
<th>E-mail</th>
<th>User</th>
<th>Admin</th>
<th>Superuser</th>
</thead>
</table>
<tbody>
#foreach($users as $user)
<tr>
<form action="{{ route('superuser.assign') }}" method="post">
<td>{{$user->first_name}}</td>
<td>{{$user->name}}</td>
<td>{{$user->email}}</td>
<td><input type="checkbox" {{ $user->hasRole('User') ? 'checked' : '' }} name="role_user"></td>
<td><input type="checkbox" {{ $user->hasRole('Admin') ? 'checked' : '' }} name="role_admin"></td>
<td><input type="checkbox" {{ $user->hasRole('Superuser') ? 'checked' : '' }} name="role_superuser"></td>
{{ csrf_field() }}
<td><button type="submit">Assign Roles</button></td>
</form>
</tr>
#endforeach
</tbody>
#endsection
The problem is that when I try to assign a role to an existing user through my front end, it throws the error
Call to a member function roles() on null
I have a UserController that looks like this:
public function postAssignRoles(Request $request)
{
$user = User::where('email', $request['email'])->first();
$user->roles()->detach();
if ($request['role_user'])
{
$user->roles()->attach(Role::where('name', 'User')->first());
}
if ($request['role_admin'])
{
$user->roles()->attach(Role::where('name', 'Admin')->first());
}
if ($request['role_superuser'])
{
$user->roles()->attach(Role::where('name', 'Superuser')->first());
}
return redirect()->back();
}
}
And my User class contains the following:
public function roles()
{
return $this->belongsToMany('App\Role', 'user_role', 'user_id', 'role_id');
}
public function hasAnyRole($roles)
{
if (is_array($roles))
{
foreach ($roles as $role)
{
if ($this -> hasRole($role))
{
return true;
}
}
}
else
{
if ($this -> hasRole($roles))
{
return true;
}
}
return false;
}
public function hasRole($role)
{
if ($this->roles()->where('name', $role)->first())
{
return true;
}
return false;
}
}
I also set up this in my middleware
public function handle($request, Closure $next)
{
if ($request->user() === null)
{
return response("U bent niet bevoegd om deze actie uit te voeren.", 401);
}
$actions = $request->route()->getAction();
$roles = isset($actions['roles']) ? $actions['roles'] : null;
if ($request->user()->hasAnyRole($roles) || !$roles)
{
return $next($request);
}
return response("U bent niet bevoegd om deze actie uit te voeren.", 401);
}
and added this in the Kernel
'roles' => \App\Http\Middleware\CheckRole::class
I think the problem is that for one reason or another $user = User::where('email', $request['email'])->first(); returns null. I tried get()instead of first(), but then I get a Method Illuminate\Database\Eloquent\Collection::roles does not exist.error.
I'm sorry for the many code snippets, but I've been struggling with this for the past 8 hours and really don't know where to search the problem anymore. Please someone help me before I go cry myself to sleep in the corner of my room and never touch Laravel again.
You are right that calling first() on your query returns null, hence the reason why you get that error.
So what you can use to prevent calling roles() on null object is to use firstOrFail() method which will throw a ModelNotFoundException which you can catch using a try catch block and handle it gracefully.
And as I can see in your view you are not sending the value of the email in your form, so you should put the email in a hidden input:
<td>
<input type="hidden" name="email" value="{{$user->email}}" />
{{$user->email}}"
</td>
not having this is why you get null result.
You must check if the values you are intending to pass are set, You can do so with isset
example #isset('$user->hasRole('User')');
I am newbie on Laravel and exploring more to learn. I am working on a project which is a Video store. It has 5 tables:
Customer (customer_id, name, address)
Category (category_id, name, description, price)
Videos (video_id, title, description, category_id , stock)
Rental (customer_id, rented_at, total_amount, interest_amount, status)
Transaction (video_id, price, transaction_id, quantity, status, returned_at [date])
I want to display in the Rental Table the Title of the Video with the corresponding Category Name and Price.
This is my code for RentalController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use App\Http\Requests;
use Carbon\Carbon;
use App\Transaction;
use App\Customer;
use App\Category;
use App\Rental;
use App\Video;
use DB;
class RentalController extends Controller {
public function __construct(){
$this->middleware('auth');
}
public function index(){
$rentals = Rental::all();
return view('rental.index', compact('rentals'));
}
public function create(){
$rental = new Rental;
$customers = Customer::pluck('name','id');
$videos = Video::pluck('title','id');
$categories = Category::pluck('price', 'id');
return view('rental.create', compact('rental', 'customers', 'videos', 'categories'));
}
public function store(Request $request) {
$this->validate($request,[
'videos.*.id' => 'required'
]);
$data = $request->all();
DB::transaction(function() use ($data) {
$rental = new Rental;
$rental->customer_id = $data['customer_id'];
$rental->rented_at = Carbon::now();
$rental->interest_amount = 0;
$rental->status = 'rented';
dd($data['videos']);
$rental->save();
foreach ($data ['videos'] as $video) {
$detail = new Transaction;
$detail->video_id = $video['id'];
$detail->rental_id = $rental->id;
$detail->quantity = 1;
$detail->status = 'rented';
$detail->price = Video::find($video['id'])->category->price;
$detail->save;
$total_amount = $detail->price;
}
$rental->total_amount = $total_amount;
$rental->save();
});
flash('Request Successfully Saved', 'success');
return redirect()->action('RentalController#index');
}
public function edit(Rental $rental) {
$customers = Customer::pluck('name','id');
$videos = Video::pluck('title','id');
$categories = Category::pluck('price', 'id');
return view('rental.edit',compact('rental', 'customers', 'videos', 'categories'));
}
public function update(Request $request, Rental $rental) {
$data = $request->all();
$rental->customer_id = $data['customer_id'];
$rental->rented_at = $data['rented_at'];
$rental->total_amount = $data['total_amount'];
$rental->interest_amount = $data['interest_amount'];
$rental->status = $data['status'];
$rental->save();
flash('Request Successfully Updated', 'success');
return redirect()->action('RentalController#index');
}
public function destroy(Rental $rental) {
$rental->delete();
flash('Request Successfully Deleted', 'success');
return redirect()->action('RentalController#index');
}
public function show(Rental $rental) {
return view('rental.show', compact('rental'));
}
}
create.blade.php
#extends('layouts.app')
#section('content')
<div class="row">
<h1 class = "page-header">Rent a Video</h1>
<div class="col-md-12">
{!! Form::model($rental, ['action' => 'RentalController#store', 'method' => 'POST', 'class' => 'form']) !!}
#include('rental.form')
{!! Form:: close() !!}
</div>
</div> #endsection
form.create.php
<div class= "form-group">
{!! Form::label('customer_id', 'Customer'); !!}
{!! Form::select('customer_id', $customers , null, ['class' => 'form-control','placeholder'=>'Customer Name']); !!}
</div>
<div class= "form-group">
{!! Form::label('total_amount', 'Total Amount'); !!}
{!! Form::text('total_amount', null, ['class' => 'form-control']); !!}
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>Title</th>
<th>Category</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>{!! Form::select('videos[1][id]', $videos, null, ['class' => 'form-control', 'placeholder' => 'Choose a video']); !!}</td>
<td></td>
<td><</td>
</tr>
<tr>
<td>{!! Form::select('videos[1][id]', $videos, null, ['class' => 'form-control', 'placeholder' => 'Choose a video']); !!}</td>
<td></td>
<td></td>
</tr>
<tr>
<td>{!! Form::select('videos[2][id]', $videos, null, ['class' => 'form-control', 'placeholder' => 'Choose a video']); !!}</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
{!! Form::submit('Save', ['class' => 'btn btn-success']); !!}
Ok first and foremost, the structure of your database should be like:
Customer (customer_id, name, address)
public function rentals()
{
return $this->hasMany('App\Rental');
}
Category (category_id, name, description, price)
public function videos()
{
return $this->hasMany('App\Video');
}
Videos (video_id, title, description, category_id , stock)
public function category()
{
return $this->belongsTo('App\Category');
}
Rental (rental_id, customer_id, rented_at, total_amount, interest_amount, status)
public function customer()
{
return $this->belongsTo('App\Customer');
}
public function transactions()
{
return $this->hasMany('App\Transaction');
}
Transaction (transaction_id, rental_id, price, video_id, quantity, status, returned_at [date])
public function rental()
{
return $this->belongsTo('App\Rental');
}
public function video()
{
return $this->belongsTo('App\Video');
}
Explained: Customer is the peak of the hierarchy , having only many Rental as its children .. Rental as being a child of Customer we declare that it belongs to a Customer .. Also having one Transaction .. Transaction belongs to a rental, as well a video.. then Video belongsTo a Category and so Category hasMany videos ..
now, on how to show data from this is:
view rentals by user
$customers = Customers::all();
foreach($customers as $customer)
{
echo '<h1>'.$customer->name .'</h1>';
echo '<h3>Rentals</h3>';
foreach($customer->rentals as $rental)
{
echo $rental->total_amount;
// and so on ..
foreach($rental->transactions as $transaction)
{
echo $transaction->video->title;
// and so on ..
echo $transaction->video->category->price;
}
}
}
Its better you go for mysql view.
Create a mysql view from a join query and use that view as Model in Laravel.
Please note. Views can only be used to read data i.e. for select queries only
I'm trying to update my pivot table approve_document where it has a extra column isApprove using ->withPivot method.
Model:
Document
class Document extends Model
{
public function sentToApprovers()
{
return $this->belongsToMany('App\Models\Approve', 'approve_document')->withPivot('isApprove');
}
}
Approve
class Approve extends Model
{
public function createdpendingDocuments()
{
return $this->belongsToMany('App\Models\Document', 'approve_document')->withPivot('isApprove');
}
}
This is where I get all my records in my approve_document.
Controller:
public function documentsSentForApproval()
{
$pendingDocumentLists = DB::table('approve_document')
->select('documents.title', 'documents.content', 'categories.category_type', 'users.username', 'approve_document.dateReceived', 'documents.id', 'approves.approver_id')
->join('documents', 'documents.id', '=', 'approve_document.document_id')
->join('categories', 'categories.id', '=', 'documents.category_id')
->join('approves', 'approves.id', '=', 'approve_document.approve_id')
->join('users', 'users.id', '=', 'approves.approver_id')
->where('approver_id', '=', Auth::id())
->orWhere('requestedBy', '=', Auth::id())
->get();
return view ('document.pending')
->with('pendingDocumentLists', $pendingDocumentLists);
}
View:
#foreach ($pendingDocumentLists as $list)
<tr class = "info">
<td>{{ $list->title }}</td>
<td>{{ strip_tags(substr($list->content, 0, 50)) }} {{ strlen($list->content) > 50 ? "..." : '' }}</td>
<td>{{ $list->category_type }}</td>
<td>{{ $list->username }}</td>
<td>{{ date('M, j, Y', strtotime($list->dateReceived)) }}</td>
<td>
#if (Auth::id() == $list->approver_id)
<a href = "{{ route ('document.pending', $list->id) }}">
<button type = "submit" class = "btn btn-success glyphicon glyphicon-thumbs-up"> Approve</button>
</a>
#endif
</td>
<td></td>
</tr>
#endforeach
You can see here I have a approve button where I need to set isApprove to true when the button is clicked. You can see that I get the current id of the document when the button was clicked.
This part of the Controller where I'm having a hard time updating my pivot table. It gives me a error MethodNotAllowedHttpException. Any tips or help would greatly appreciated!
public function updateIsApprove($id)
{
$document = new Document();
foreach ($document as $update)
{
$approve = new Approve();
$document->sentToApprovers()->updateExistingPivot([$approve->id => ['isApprove' => '1']],false);
}
return redirect()->route('document.pending');
}
routes:
Route::post('/documents/pending/approve/{id}',
[
'uses' => '\App\Http\Controllers\DocumentController#updateIsApprove',
'as' => 'document.pending',
]);
public function updateExistingPivot($id, array $attributes, $touch = true)
First parametr should be id of related thing.
public function updateIsApprove($documentId, $approveId)
{
$document = Document::find($documentId);
if (!$document) {
// Handle error that document not exists.
}
$approve = $document->sentToApprovers()->find($approveId);
if (!$approve) {
// Handle that approve not exists or is not related with document.
}
$document->sentToApproves()->updateExistingPivot($approve->id, ['isApprove' => 1]);
return redirect()->route('document.pending');
}
MethodNotAllowedHttpException is not for your controller but is for your Route. As you can see, in your Routes file, you have Route for handling POST request, but in your view you are making a GET request by accessing the URL directly.
So, just change the POST route to GET in your Routes file.
Route::get('/documents/pending/approve/{id}',
[
'uses' => '\App\Http\Controllers\DocumentController#updateIsApprove',
'as' => 'document.pending',
]);