I'm using laravel 8 for CRUD.. i try using create and store function in controller and it's perfecly fine then the data will store in database. Now, i try to use show function which the data that i created will show to user once they click the 'show' button. The most error i found is undefined $product
here is my blade for index.blade
<a class="btn btn-info" href="show-index">Show</a>
Here is my blade for show.blade.php
<div class="row">
<div class="col-lg-12 margin-tb">
<div class="pull-left">
<h2> Show Product</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="pro_index"> Back</a
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Name:</strong>
{{ $product->name }}
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Details:</strong>
{{ $product->detail }}
</div>
</div>
</div>
Here is my ProductController.php
class ProductController extends Controller
{
public function index()
{
$products = Product::all();
return view('products.pro_index',compact('products'));
}
public function create()
{
return view('products.create');
{
public function store(Request $request)
{
$request->validate([
'name' => 'required',
'detail' => 'required',
]);
$product= Product::create([
'name' => $request->name,
'detail' => $request->detail,
]);
return redirect('/pro_index') ->with('success','Your record has been updated');
}
public function show (Product $product)
{
$product = Product::find($product);
return view('products.show');
}
}
here is my web.php
Route::get('/show-index', [App\Http\Controllers\ProductController::class, 'show'])->name('show');
You don't need this line of code because you already have model binding in place
$product = Product::find($product);
Change anchor href from href="show-index" to href="{{ route('show', $product) }}
In controller
public function show (Product $product)
{
return view('products.show', compact('product'));
}
in web.php
Route::get('/show/{product}', [App\Http\Controllers\ProductController::class, 'show'])
->name('show');
For more : https://laravel.com/docs/8.x/routing#route-model-binding
Related
After setting up my profile page my uploaded images initially produced an image on my local host. However lately it shows up as an icon instead https://i.stack.imgur.com/pp0Yt.png
I should note I am using php 7.3.19
profiles/index.blade.php
<div class="container">
<div class="row">
<div class="col-3 p-5">
<img src="{{ $user->profile->profileImage() }}" class="rounded-circle w-100">
</div>
<div class="col-9 pt-5">
<div class="d-flex justify-content-between align-items-baseline">
<div class="d-flex align-items-center pb-3">
<div class="h4">{{ $user->username }}</div>
<follow-button user-id="{{ $user->id }}" follows="{{ $follows }}"></follow-button>
</div>
#can('update', $user->profile)
Add New Post
#endcan
</div>
#can('update', $user->profile)
Edit Profile
#endcan
<div class="d-flex">
<div class="pr-5"><strong>{{ $postCount }}</strong> posts</div>
<div class="pr-5"><strong>{{ $followersCount }}</strong> followers</div>
<div class="pr-5"><strong>{{ $followingCount }}</strong> following</div>
</div>
<div class="pt-4 font-weight-bold">{{ $user->profile->title }}</div>
<div>{{ $user->profile->description }}</div>
<div>{{ $user->profile->url }}</div>
</div>
</div>
<div class="row pt-5">
#foreach($user->posts as $post)
<div class="col-4 pb-4">
<a href="/p/{{ $post->id }}">
<img src="/storage/{{ $post->image }}" class="w-100">
</a>
</div>
#endforeach
</div>
</div>
#endsection
Is there an issue in the way I am picking it up from the storage?
I used 'php artisan storage:link'
create.blade.php
<div class="container">
<form action="/p" enctype="multipart/form-data" method="post">
#csrf
<div class="row">
<div class="col-8 offset-2">
<div class="row">
<h1>Add New Image</h1>
</div>
<div class="form-group row">
<label for="caption" class="col-md-4 col-form-label">Post Caption</label>
<input id="caption"
type="text"
class="form-control{{ $errors->has('caption') ? ' is-invalid' : '' }}"
name="caption"
value="{{ old('caption') }}"
autocomplete="caption" autofocus>
#if ($errors->has('caption'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('caption') }}</strong>
</span>
#endif
</div>
<div class="row">
<label for="image" class="col-md-4 col-form-label">Post Image</label>
<input type="file" class="form-control-file" id="image" name="image">
#if ($errors->has('image'))
<strong>{{ $errors->first('image') }}</strong>
#endif
</div>
<div class="row pt-4">
<button class="btn btn-primary">Add New Post</button>
</div>
</div>
</div>
</form>
</div>
#endsection
PostsController.php
<?php
namespace App\Http\Controllers;
use App\Post;
use Illuminate\Http\Request;
use Intervention\Image\Facades\Image;
class PostsController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
$users = auth()->user()->following()->pluck('profiles.user_id');
$posts = Post::whereIn('user_id', $users)->with('user')->latest()->paginate(5);
return view('posts.index', compact('posts'));
}
public function create()
{
return view('posts.create');
}
public function store()
{
$data = request()->validate([
'caption' => 'required',
'image' => ['required', 'image'],
]);
$imagePath = request('image')->store('uploads', 'public');
$image = Image::make(public_path("storage/{$imagePath}"))->fit(1200, 1200);
$image->save();
auth()->user()->posts()->create([
'caption' => $data['caption'],
'image' => $imagePath,
]);
return redirect('/profile/' . auth()->user()->id);
}
public function show(\App\Post $post)
{
return view('posts.show', compact('post'));
}
}
ProfilesController.php
<?php
namespace App\Http\Controllers;
use App\Profile;
use App\User;
use Illuminate\Http\Request;
use Intervention\Image\Facades\Image;
use Illuminate\Support\Facades\Cache;
class ProfilesController extends Controller
{
public function index(User $user)
{
$follows = (auth()->user()) ? auth()->user()->following->contains($user->id) : false;
$postCount = Cache::remember(
'count.posts.' . $user->id,
now()->addSeconds(30),
function () use ($user) {
return $user->posts->count();
});
$followersCount = Cache::remember(
'count.followers.' . $user->id,
now()->addSeconds(30),
function () use ($user) {
return $user->profile->followers->count();
});
$followingCount = Cache::remember(
'count.following.' . $user->id,
now()->addSeconds(30),
function () use ($user) {
return $user->following->count();
});
return view('profiles.index', compact('user', 'follows', 'postCount', 'followersCount', 'followingCount'));
}
//($user = (User::findOrFail($user));)
//('user' => $user)
//
public function edit(User $user)
{
$this->authorize('update', $user->profile);
return view('profiles.edit', compact('user'));
}
public function update(User $user)
{
$this->authorize('update', $user->profile);
$data = request()->validate([
'title' => 'required',
'description' => 'required',
'url' => 'url',
'image' => '',
]);
if (request('image')) {
$imagePath = request('image')->store('profile', 'public');
$image = Image::make(public_path("storage/{$imagePath}"))->fit(1000, 1000);
$image->save();
$imageArray = ['image' => $imagePath];
}
auth()->user()->profile->update(array_merge(
$data,
$imageArray ?? []
));
return redirect("/profile/{$user->id}");
}
public function show($user_id)
{
$user = User::find(1);
$user_profile = Profile::info($user_id)->first();
return view('profiles.show', compact('profile', 'user'));
}
public function profile()
{
return $this->hasOne('Profile');
}
}
Use asset helper function to get the uploaded image URL.
<img src="{{ asset('storage/' . $post->image) }}" class="w-100">
OR
<img src="{{ asset(Storage::url($post->image)) }}" class="w-100">
I'm not being able to append the result with query. I'm filtering the result with category on the page and trying to add pagination. When a user clicks on category only category related products should be displayed and on pagination I want to keep the selected category. I'm getting this error:
Facade\Ignition\Exceptions\ViewException
Call to undefined method Illuminate\Database\Eloquent\Builder::appends() (View: D:\Xampp\htdocs\ProjectName\resources\views\products\index.blade.php)
I have tried this from laravel docs
{{ $users->appends(['category' => 'query'])->links() }}
Here's my Controller:
public function index(Request $request)
{
// If the category is selected
if(request()->category) {
$products = Product::with('categories')->whereHas('categories', function ($query){
$query->where('slug', request()->category);
});
$categories = Category::all();
$categoryName = optional($categories->where('slug', request()->category)->first())->name;
}else {
$products = Product::paginate(9);
$categories = Category::all();
$categoryName = 'All Products';
}
return view('products.index')->with([
'products' => $products,
'categories' => $categories,
'categoryName' => $categoryName,
]);
}
This is my blade file:
<h4>{{ $categoryName }}</h4>
#forelse ($products as $product)
<div class="card mb-3 shadow" style="">
<div class="row no-gutters">
<div class="col-md-4 d-flex justify-content-around p-2 border">
<img src="/storage/products/{{ $product->image }}" class="card-img">
</div>
<div class="col-md-8 p-2">
<div class="card-body">
<h5 class="card-title">{{ $product->title}}</h5>
<p class="card-text"> {!! \Illuminate\Support\Str::limit($product->text, $limit = 100) !!} </p>
<div class=""><button class="btn btn-outline-warning float-left">View Cataloge</button>
</div>
</div>
</div>
</div>
</div>
#empty
<div class="card">
<div class="card-title p-5 shadow bg-light">
<h5>No products found</h5>
</div>
</div>
#endforelse
<div class=" d-flex justify-content-around">
{{ $products->appends(request()->input())->links() }}
</div>
Here you are missing paginate(9) also pass ($request) in closure function
public function index(Request $request)
{
// If the category is selected
if (!empty($request)) {
$products = Product::whereHas('categories', function ($query) use ($request) {
$query->where('slug', $request->category);
})->paginate(9);
$categories = Category::all();
$categoryName = optional($categories->where('slug', request()->category)->first())->name;
return view('products.index')->with([
'products' => $products,
'categories' => $categories,
'categoryName' => $categoryName,
]);
}
else {
$products = Product::paginate(9);
$categories = Category::all();
$categoryName = 'All Products';
return view('products.index')->with([
'products' => $products,
'categories' => $categories,
'categoryName' => $categoryName,
]);
}
}
My Seeder looks like this:
class ContentTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
DB::table('content')->insert(
[
[
'name' => '<div class="row">
<div class="col-xs-2 col-sm-2 col-md-4 col-lg-4"></div>
<div class="col-xs-8 col-sm-8 col-md-4 col-lg-4">
<form method="get" action="/group-register">
{{ csrf_field() }}
<div class="input-group">
<input type="group_id" class="form-control" name="group_id" placeholder="{{ __(\'site.group_search\') }}">
<span class="input-group-btn">
<button type="submit" class="btn btn-default">{{ __(\'site.group_search_button\') }}</button>
</span>
</div>
</form>
<hr>
<p>
{{ __('site.group_register') }}
</p>
</div>
<div class="col-xs-2 col-sm-2 col-md-4 col-lg-4"></div>
</div>',
'title' => 'home',
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
] ]
);
}
}
Then I have a router that looks like this:
Route::get('/{title}', 'ContentController#show');
The controller:
class ContentController extends Controller
{
public function show($id)
{
$content = Content::where('title', '=', $id)->get();
return view('content.show', compact('content'));
}
}
And the show.blade.php:
#section('content')
<div class="main-content">
#foreach($content as $item)
{!! $item['name'] !!}
#endforeach
</div>
#endsection
And the output looks like this:
This is how it looks
But if I call the same seeded code from basic blade.php then it looks correctly:
this is how it should look like
Replace this:
$content = Content::where('title', '=', $id)->get();
With this:
$content = Blade::compileString(Content::where('title', '=', $id)->get());
And dont forget to import the Blade facade:
use Illuminate\Support\Facades\Blade;
Yesterday I started with Laravel, currently busy with my first project, a simple news page.
Unfortunately, I've met some problems while validating my post request, I've tried to search on Google for my issue. And I tried to use those fixes, but strange enough I had no result.
The problem is:
When I post data the normal 'form page' will be shown without any errors. I'm aware that I have double error outputs, it's just for the test.
What do I want to reach?
I want that the validation error will be shown
routes.php
<?php
Route::group(['middleware' => ['web']], function() {
Route::get('/', function() {
return redirect()->route('home');
});
Route::get('/home', [
'as' => 'home',
'uses' => 'HomeController#home',
]);
Route::get('/add_article', [
'as' => 'add_article',
'uses' => 'HomeController#add_article',
]);
Route::post('/add_article', [
'as' => 'add_article.newarticle',
'uses' => 'HomeController#post_article',
]);
});
HomeController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\News;
class HomeController extends Controller
{
public function home(News $news)
{
$articles = $news->orderBy('id','desc')->take(3)->get();
return view('home.home')->with('articles', $articles);
}
public function add_article()
{
return view('home.add_article');
}
public function post_article(Request $request)
{
$this->validate($request, [
'title' => 'required|max:64',
'content' => 'required|max:2048',
]);
// $newNews = new News;
// $newNews->title = $request->title;
// $newNews->content = $request->content;
// $newNews->save();
}
}
add_article.blade.php
#extends('templates.default')
#section('content')
<div class="row">
<div class="col-sm-12 col-md-6 col-lg-6 col-xl-6 offset-md-3 offset-lg-3 offset-xl-3">
<p class="lead">New news article</p>
<div class="card">
<div class="card-header">
<h5 class="mb-0"> </h5>
</div>
<div class="card-body">
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<form method="post" action="{{ route('add_article.newarticle') }}">
<div class="form-group">
<label for="title" style="margin-bottom:0px;">
Title:
</label>
<input class="form-control" type="text" name="title" placeholder="Please enter your title!" id="title">
#if ($errors->has('title'))
{{ $errors->first('title') }}
#endif
</div>
<div class="form-group">
<label for="content" style="margin-bottom:0px;">
Content:
</label>
<textarea class="form-control" rows="3" name="content" placeholder="Please enter your message!" id="content" style="resize:none;"></textarea>
#if ($errors->has('content'))
{{ $errors->first('content') }}
#endif
</div>
<div class="form-group text-right">
<button class="btn btn-primary" type="submit">
Create news
</button>
</div>
{{ csrf_field() }}
</form>
</div>
</div>
</div>
</div>
#endsection
I hope someone can help me to resolve this issue!
use App\Http\Requests;
Remove This from HomeController.php and try.
Your validation is passing but you are not doing anything after so it's not going to show anything unless you tell it to.
Also make sure you use $request->all() instead of $request in the validator as the first one will return the actual input values that were submitted.
use Validator;
public function post_article(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required|max:64',
'content' => 'required|max:2048',
]);
if ($validator->fails()) {
return redirect('home')
->withErrors($validator)
->withInput();
}
// $newNews = new News;
// $newNews->title = $request->title;
// $newNews->content = $request->content;
// $newNews->save();
return redirect()->route('home')->with('message', 'Article created.');
}
}
Then in your view add the following at the top:
#if(Session::has('message'))
<div class="alert alert-success">
×
{{ Session::get('message') }}
</div>
#endif
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
Based on those validation rules you will only see errors when the title is empty or longer than 64 characters, or the content is empty or longer than 2048 characters. Make sure the data you are testing with is long enough to trigger any errors.
For data that passes validation the code currently does not save (commented out), nor does it return a new location or view so it will show a blank page. You should probably save the data and redirect to the index or a show page with a success message.
i cant seem to fix my issue when i delete a task it redirects me to dashboard i can see in controller it is currently redirecting to /dashboard page however when i try to fix this it just errors out :/ i want it to acheive the same result the create redirection does
public function createTaskPage(Request $request, $slug) {
$project = Project::where('slug', $slug)->firstOrFail();
// Validate it has a body.
$validate = validator(
$request->toArray(), [
'task' => 'required',
]);
if ($validate->fails()) {
return response()->json([], 400);
}
$tasks = new Task;
$tasks->project_id = $project->id;
$tasks->body = $request->task;
$tasksCreate = Auth::user()->tasks()->save($tasks);
//return response()->json([], 201);
return redirect()->to('/project/' . $project->slug);
}
public function doDeleteTask($id) {
try {
$tasks = Task::where('user_id', Auth::user()->id)->findOrFail($id);
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $ex) {
return response()->json([], 404);
}
$tasks->delete();
//return response()->json([], 204);
return redirect()->to('/dashboard');
}
This is the Form where delete button is
<div class="col-md-3">
<div class="panel panel-default shadow">
<div class="panel-body">
<div class="row text-center">
<h4><strong>{{ str_limit(strip_tags($project->name), 20) }}</strong></h4>
<h5>{{ $project->created_at }}</h5>
</div>
<div class="row text-center" style="margin:5px;">
{{ ($project->description) }}
</div>
<div class="row text-center">
<form action="{{ url('/project/'.$project->id) }}" method="POST">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<button type="submit" class="btn btn-link btn-sm" onclick="return ConfirmDelete(this)" style="margin:5px;"><i class="fa fa-ban fa-3x" aria-hidden="true"></i></button>
<i class="fa fa-arrow-circle-o-right fa-3x" aria-hidden="true"></i>
</form>
</div>
</div>
</div>
This is my Delete route & create route
Route::delete('/task/{id}', 'TaskController#doDeleteTask'); // Delete a task
Route::post('/project/{slug}/task', 'TaskController#createTaskPage')->name('task');
If you have a project relation defined in tasks, you can do this:
public function doDeleteTask($id) {
try {
$tasks = Task::where('user_id', Auth::user()->id)->findOrFail($id);
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $ex) {
return response()->json([], 404);
}
$project = $tasks->project;
$tasks->delete();
return redirect()->to('/project/' . $project->slug);
}