Laravel Patch Request doesn't update database table - php

For our Task attributes we have the following: task_id as primary key, user_id, stage_id and project_id as foreign keys, completed as boolean and a description. Our goal is to display the tasks under a project and by checking the checkbox right next to them, it should mark them as complete. The problem is in our database the 'complete' status doesnt change. We are using PhpMyAdmin. We have a separate controller called ProjectTasksController for handling the logic and a form in our show.blade.php view for sending the request. Any help would be greatly appreciated.
#extends('layouts.app')
#section('content')
<div class="display-3">{{$project->name}}</div>
<a class="nav-link" href="/projects/{{$project->project_id}}/edit"><i class="material-icons">edit</i></a>
#if ($project->image)
<div class="row">
<div class="col-12">
<img src="{{ asset('storage/' . $project->image) }}" alt="...." class="img-thumbnail">
</div>
</div>
#elseif(!$project->image)
no image
#endif
#if ($project->tasks->count())
<div>
#foreach ($project->tasks as $task)
<div>
<form method="POST" action="/tasks/{{$task->task_id}}">
{{method_field('PATCH')}} {{-- #method('PATCH') --}}
#csrf
<label class="checkbox {{$task->completed ? 'is_complete' : ''}} " for="completed">
<input type="checkbox" name="completed" onChange="this.form.submit()" {{$task->completed ? 'checked' : ''}} >
{{$task->description}}
</label>
</form>
</div>
#endforeach
</div>
#endif
#endsection
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Task;
class ProjectTasksController extends Controller{
public function update(Task $task)
{
$task->update([
'completed' => request()->has('completed')
]);
return back();
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
protected $guarded = [];
protected $primarykey = ['task_id'];
protected $fillable = ['user_id','stage_id','project_id','completed','description'];
public function stage(){
return $this->belongsTo(Stage::class);
}
public function user(){
return $this->belongsTo(User::class);
}
public function project(){
return $this->belongsTo(Project::class);
}
}
{
_method: "PATCH",
_token: "ljiwu8bEtAkRqSUOXllmaRbSujavHNYNRJR5TMcy",
completed: "on"
}
Route::patch('/tasks/{task_id}', 'ProjectTasksController#update');

Your controller method was not correct, hint of Task $task is just a instance of Task not the collection or a single Model.And you have not specify your Request $request to get this work request()->has('completed') in method arguments.You need to edit your method in following way:
public function update(Request $request,$task_id)
{
Task::find($task_id)->update([
'completed' => $request->has('completed')
]);
return back();
}
Note: $request->has('completed') will return Boolean; if you want exact value,then you need to retrieve as $request->get('completed')

If you want to use route model binding the name of your parameter in the update function should match the route parameter:
Route::patch('/tasks/{task}', 'ProjectTasksController#update');
Replace protected $primaryKey = ['task_id]'; with protected $primaryKey ='task_id' in the Task model. It should be a string, not an array.

Related

Laravel how to slove Undefined variable in included modal

How to slove Undefined variable error exception for variable declared in another controller.
I have OrderController and CustomerController.
In CustomerController i pass $customerTypes[] to view.
Then that view i try to import in antoher view of OrderController and than i get undefended variable. So OrderController does not know about $customerTypes[].
How is possible to slove that dependency?
If i declare $customerTypes[] in OrderController that not be clean code!No point for that var in order.
CustomerController
namespace App\Http\Controllers;
class CustomerController extends BaseController
{
/**
* Index
*/
public function index()
{
$orders = Order::orderBy('created_at', 'desc')->paginate(20)->withQueryString();
$customerTypes = CustomerType::orderBy('name')->get();
return view('customer.index', [
'customerTypes'=> $customerTypes
]);
}
}
/resources/views/customer/create_modal.blade.php
<!-- Modal -->
<div class="modal fade">
#if($customerTypes)
#foreach($customerTypes as $type)
<div class="form-check">
<input type="checkbox" value="{{ $type->id }}">
<label>{{ $type->name }}</label>
</div>
#endforeach
#endif
</div>
OrderController
namespace App\Http\Controllers;
class OrderController extends BaseController
{
/**
* Index
*/
public function index()
{
//....
return view('customer.index', [
'orders'=> $orders
]);
}
}
/resources/views/order/index.blade.php
here i include modal and get error.
#include('customer.create_modal')

LARAVEL 7 - How to pass variables to views

I have two tables, Companies and Projects. A company hasMany projects and a project belongsTo a company.
Company.php model
protected $fillable = [
'id', 'name', 'description'
];
public function projects()
{
return $this->hasMany('App/Project');
}
Project.php model
protected $fillable = [
'name', 'description', 'company_id', 'days'
];
public function company()
{
return $this->belongsTo('App/Company');
}
From my index.blade.php, I list the companies only and I have made them clickable so that when a user clicks on a company listed, they are taken to show.blade.php where the name of the company and the projects that belong to that company are displayed like so.
<div class="jumbotron">
<h1>{{ $company->name }}</h1>
<p class="lead">{{ $company->description }}</p>
</div>
<div class="row">
#foreach($company->projects as $project)
<div class="col-lg-4">
<h2>{{ $project->name }}</h2>
<p class="text-danger">{{ $project->description }}</p>
<p><a class="btn btn-primary" href="/projects/{{ $project->id }}" role="button">View Projects »</a></p>
</div>
#endforeach
</div>
Now am getting an undefined variable $project error. So I decided to declare variable in my show() function of the CompaniesController.php like so
public function show(Company $company)
{
$company = Company::find($company->id);
$projects = Company::find(1)->projects;
return view('companies.show', ['company' => $company, 'projects' => $projects]);
}
And access variable in show.blade.php like so
<div class="jumbotron">
<h1>{{ $company->name }}</h1>
<p class="lead">{{ $company->description }}</p>
</div>
<div class="row">
#foreach($projects as $project)
<div class="col-lg-4">
<h2>{{ $project->name }}</h2>
<p class="text-danger">{{ $project->description }}</p>
<p><a class="btn btn-primary" href="/projects/{{ $project->id }}" role="button">View Projects »</a></p>
</div>
#endforeach
</div>
Now am getting a Class 'App/Project' not found error when I access show.blade.php. I am having a challenge passing company projects to the view. Any help will be appreciated. Here are my routes;
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
Route::resource('companies', 'CompaniesController');
Route::resource('projects', 'ProjectsController');
I would be hilarious if I am right....
In your models where defining relations replace App/Project with App\Project. Do the same for Company.... Replace "/" with "\".
You have to namespace Project class properly
Make sure file name is Project.php
Make sure inside Project.php namespace declaration is correct: namespace App;
Make sure class name inside Project.php is 'Project' : class Project extends Model { ...
Make sure you have imported it in controller. use App\Project
After all that done you will not get error:
Class 'App/Project' not found
You have correctly done passing variable in view but have a look here for another examples and methods passing about it:
https://laravel.com/docs/7.x/views
Hope this helps you
You're already using model binding. In your show method, you do not need to find. just return what you need
public function show(Company $company)
{
return view('companies.show', ['company' => $company];
}
In your view, you can then do:
#foreach($company->projects as $project)
...
#endforeach

laravel How to display items of one category on the relationship between item and category tables

I asked this question before but didnt get any answer,hope you have the solution.
As I have 2 tables, items and categories so every item has one category and one category can have many items.
my problem is when using groupby function but it shows one item for every category
item model:
class Item extends Model
{
protected $table="items";
protected $fillable=
['item_title','category_id','item_price','item_details','item_image'];
protected $primaryKey='item_id';
public $timestamps=false;
public function categories()
{
$this->hasOne('App\category','category_id','category_id');
}
}
category model
class Category extends Model
{
protected $table="categories";
protected $fillable=['category_name'];
protected $primaryKey='category_id';
public $timestamps=false;
public function items()
{
$this->hasMany('App\items','category_id','category_id');
}
}
Controller
class HomeController extends Controller
{
public function getItems()
{
$items = Item::groupBy('category_id')->get();
return view('home',compact('items'));
}
}
HTML
#foreach($items as $indexKey => $item)
<div class="MenuPage_contentArea">
<div class="Category_root" id="one">
<div class="Category_categoryHeader">
<div><h2 class="Category_name">{{$item->item_category}}</h2></div>
<div class="Category_description"></div>
</div>
<div class="Category_itemsContainer">
<div class="Category_itemContainer">
<button class="Item_root Button_root">
<div class="Item_image" style="background-image: url('{{ asset('images/' . $item->item_image) }}');"></div>
<div class="Item_itemContent">
<div class="Item_topSection">
<span class="Item_name">{{$item->item_title}}</span>
<span class="Item_price">${{$item->item_price}}</span></div>
<div class="Item_description">{{$item->item_details}}</div>
</div>
</button>
</div>
</div>
</div>
</div>
#endforeach
You are grouping at SQL level, but if you want all of the items in a category grouped in a Collection, then use groupBy method from Collection. Use all()
method to get a collection of all items, then use groupBy() method to group the items by category_id:
HOME CONTROLLER
class HomeController extends Controller
{
public function getItems()
{
$items = Item::all()->groupBy('category_id');
return view('home',compact('items'));
}
}
Access in your blade File as:
#foreach($items as $category_id => $categoryItems)
Category ID: {{ $category_id }} <br>
#foreach($categoryItems as $item)
<!-- Display Item Details Here -->
#endforeach
#endforeach
Hope it helps you. :)

LARAVEL Eloquent: link post to user then user to profile

I am aiming on retrieving the user image (from profile table column 'profile_img') and display on each post's footer.
I can retrieve the name of the author using $post->author->name and the profile picture using $post->author->profile->profile_image but it only works when i have a single record (post). when there is more than one record i get an error Trying to get property 'profile' of non-object (View: xampp/........../home.blade.php)
Can somebody show me where do i go wrong??
Models:
User
public function post()
{
return $this->hasMany('App\Post');
}
public function profile()
{
return $this->hasOne('App\Profile');
}
Profile
public function user()
{
return $this->belongsTo('App\User');
}
Post
public function author()
{
return $this->belongsTo('App\User', 'id');
}
controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
class MainController extends Controller
{
public function index() {
$posts = Post::paginate(9);
return view('pages.home')->with('posts', $posts);
}
home view
#if(count($posts) > 0)
#foreach($posts as$posts)
<div>
<div class="post-title"><h3>{{$post->title}}</h3></div>
<div class="post-description">
{!!mb_substr($post>body,10,rand(35,40)) !!} ....
</div>
<div class="featured-details">
<div class="p-clearfix">
<img class="authorimg"src="/storage/profile_images/{{ $post->author->profile->profile_image }}">
<div class="author-title lite">{{ $post->author->name }}</div>
<div class="lite thumbnail-date">{{ date('M j, Y', strtotime($post->created_at)) }}</div>
</div>
</div>
</div>
<hr>
#endforeach
#else
no post yet
#endif
There appears to be some issues in your home view. Try it again with this code and see.
Home View
#if(count($posts) > 0)
#foreach($posts as $post)
<div>
<div class="post-title"><h3>{{$post->title}}</h3></div>
<div class="post-description">
{!!mb_substr($post>body,10,rand(35,40)) !!} ....
</div>
<div class="featured-details">
<div class="p-clearfix">
<img class="authorimg"src="/storage/profile_images/{{ $post->author->profile->profile_image }}">
<div class="author-title lite">{{ $post->author->name }}</div>
<div class="lite thumbnail-date">{{ date('M j, Y', strtotime($post->created_at)) }}</div>
</div>
</div>
</div>
<hr>
#endforeach
#else
no post yet
#endif
You can even go further and avoid the n+1 problem for authors by running your eloquent model query like this om your controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
class MainController extends Controller
{
public function index() {
$posts = Post::with("author")->paginate(9);
return view('pages.home')->with('posts', $posts);
}
I hope this helps.
In your controller index method try with :
public function index() {
$posts = Post::with("author.profile")->paginate(9);
return view('pages.home')->with('posts', $posts);
}
And update post model relationship:
public function author()
{
return $this->belongsTo('App\User', 'user_id'); // update to users table foreign key
}

Creating a hasMany Relation in Laravel 5

I'm trying to create a Tag/Content structure. A content object is assigned to a Tag object and Tag objects can be assigned to many Contents. I'm getting an error:
Trying to get property 'name' of non-object (View: D:\laragon\www\project1\resources\views\contents\show.blade.php)
These are my Models:
Content:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Content extends Model {
public function tag() {
return $this->belongsTo('App\Tag');
}
}
Tag:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model {
public function contents() {
return $this->hasMany('App\Content');
}
}
ContentController:
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id) {
$content = Content::find($id);
return View('contents.show')
->with('content', $content);
}
show.blade.php:
#extends('layouts.app')
#section('content')
<div class="container">
<h1> {{ $content->tag->name }} - {{ $content->title }} </h1>
<div class="row">
<div class="col-lg-12">
Title: {{ $content->title }}
</div>
<div class="col-lg-12">
Body: {{ $content->body }}
</div>
<div class="col-lg-12">
Tag: {{ $content->tag }}
</div>
<hr />
<div class="col-lg-12">
{!! link_to('contents', 'Back', ['class' => 'btn btn-danger']) !!}
</div>
</div>
</div>
#endsection
The error I'm getting is from h1 tag: {{ $content->tag->name }}
Any Ideas? Thanks in advance :)
You have to check "$content->tag" is valid before call "$content->tag->name".
The problem is that in the table contents should have tag_id, but you can solve it in this way in the Content model
class Content extends Model {
public function tag() {
return $this->belongsTo('App\Tag');
}
}
class Tag extends Model {
public function contents() {
return $this->hasMany('App\Content', 'tag');
}
}
This was the solution:
Change column name tag to tag_id and change return $this->belongsTo('App\Tag'); to return $this->belongsTo('App\Tag','tag_id');
The final code was:
Content Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Content extends Model {
public function tag() {
return $this->belongsTo('App\Tag','tag_id');
}
}
Tag Model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model {
public function contents() {
return $this->hasMany('App\Content');
}
}
Thank you all for the help.
Refer the table name inside model
protected $table ="<table_name>"

Categories