Laravel: a simple MVC example - laravel

I'm new to Laravel and the documentation's basic task list returns Views from the Route(web.php) but I want to use a Controller to return an image file.
So I have for my route:
Route::get('/products', 'ProductController#index');
Then my ProductController action (please ignore comments as I'm using index to simplify things):
<?php
namespace App\Http\Controllers;
use App\Product;
use Illuminate\Http\Request;
class ProductController extends Controller
{
/**
* Display a listing of the resource.
*
#return \Illuminate\Http\Response
Fetch and return all product records.
*/
public function index()
{
//
//return response()->json(Product::all(), 200);
return view('/pages/product', compact('product'));
}
And my product.blade.php (nested in views/pages/product):
<img src="/images/product/Frozen_Ophelia_800x.png">
I keep getting a ReflectionException Class App\Product does not exist.
I got this working when I just returned a view from the route. I'm getting a ReflectionException
Class App\Product does not exist so I think it's something at the top, ie. use App\Product; that is wrong.
Edit (below is my App\Product nested in app/Providers):
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Product extends Model
{
//
use SoftDeletes
protected $fillable = [
'name', 'price', 'units', 'description', 'image'
];
public function orders(){
return $this->hasMany(Order::class);
}
}

Assuming App\Product model exists, correct code should be:
public function index() {
$product = Product::all();
return view('pages.product', compact('product'));
}
Check the docs.
PS did you call a $ composer dumpautoload? ReflectionException Class error is often related to new class autoloading (eg. new classes in a packages)

view function should have any view template not any url or route. Of you have file views/pages/product.blade.php then use
view('pages.product',compact('product'));

Related

Lumen - Using factory() function in tests make error - Undefined Function

I'm using Lumen 8.3 ,wanted to use factory() function in my tests, it gives me
Undefined Function ,there is nothing useful in the Docs of Lumen
Am i missing something here?
class ProductTest extends TestCase
{
public function test_if_can_send_products_list(){
$products = factory('App/Products',5)->make();
$this->json('post','/payouts',$products)
->seeJson([
'created' => true,
]);
}
}
->
Error: Call to undefined function factory()
It's better to use direct class like that:
$products = factory(Products::class, 5)->create();
don't forget to add Products model usage (namespace).
Edit
You should create Factory:
<?php
namespace Database\Factories;
use App\Products;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class ProductFactory extends Factory
{
protected $model = Products::class;
public function definition(): array
{
return [
'name' => $this->faker->unique()->userName()
];
}
}
And add HasFactory Trait to your model:
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Products extends Model {
use HasFactory;
}
you can also use it like this
Products::factory()->count(5)->make();
I just uncommented these lines in app.php file
$app->withFacades();
$app->withEloquent();
Apparently Laravel 8 removed the 'factory' helper, and it seems Lumen followed that path without updating documentation;
#Faesal Answer is the correct way to do it these days;
remember to add use HasFactory; to your Model.

How to get the "catagory name" in Laravel?

How to get "category name" show in the product table not as "category_id"?
I already try to combine any solutions for this. But still can't solve this prob.
I'd love to hear other suggestions from the masters here.
Category Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Kategori extends Model
{
use HasFactory;
protected $casts = [
'updated_at' => 'datetime:d/m/Y, H:i:s'
];
public function Kategori()
{
return $this->hasMany('App\Models\Produk');
}
}
Product Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Produk extends Model
{
use HasFactory;
protected $casts = [
'updated_at' => 'datetime:d/m/Y, H:i:s'
];
public function Produk()
{
return $this->belongsTo('App\Models\Kategori', 'kategori_id');
}
}
Category Table
Product Table
Product Controller >>>> in my opinion may be my prob at here, but not so sure.
<?php
namespace App\Http\Controllers;
use App\Models\Produk;
use RealRashid\SweetAlert\Facades\Alert;
use Yajra\Datatables\DataTables;
use Illuminate\Http\Request;
class ProdukController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function json(){
return Datatables::of(Produk::all())->make(true);
}
public function index(){
return view('back.produk.show');
}
}
Pass the other model using your relationship
public function json(){
return Datatables::of(Produk::with('produk')->get())->make(true);
}
to which say that is named $produks, you can access it as
$produk->produk->nama;
As a side note, Do name your relationships the names of the other model.
for example, in the Kategori class, the relationship to Produk should be named produks (it is a hasMany relationship) as opposed to Kategori. Similarly, in the Produk class, the relationship to Kategori being named kategori() to which from the above answer you access it like
$produk->kategori->nama;
You should use:
public function json(){
return Datatables::of(Produk::with('Kategori')->all())->make(true);
}
I recommend to use camelCase for method names. I'm not sure how Datatables will handle this case.
In your ProdukController you need pass below code.
$result = Produk::with('Produk')->get();
When you dd($result);, you should see the related models in the relations array attribute.
To access the relations' properties from there, it is simply
$result->Produk->catagory_name

How to call multi table data in single page if all data is not related to each other

I have a controller named HomeController and I want to call data from banner table. I have a banner table and a BannerController. I had tried to get data in HomeController like
public function index()
{
$data = banner::all();
echo "hello";
print_r($data);exit;
return view('home');
}
but it's not showing me anything.
My banner model is like
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class banner extends Model{
protected $table='banners';
}
?>
And my route is like
Route::get('\home','HomeController#index')->name('home')
Your model, assuming your table name is 'banners':
App\Banner.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Banner extends Model
{
protected $table = 'banners';
}
From HomeController, sending $data to your view can be done like so:
App\Http\Controllers\HomeController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Banner;
class HomeController extends Controller
{
public function index()
{
$data = Banner::all();
return view('home', compact('data'));
}
}
And you should have the results of Banner:all() in your home blade/view which will be accessible as $data
In your blade file you can access it like so (just an example):
#foreach ($data as $banner)
{{ $banner }}
#endforeach
Try This Method - call multiple table data in a single page
public function index()
{
return View('index')
->with('test1', table1::all())
->with('test2', table2::all())
->with('test3', table3::all());
}

Laravel: Class not found if it is called from a Trait

After creating several Apps with Laravel and using softDelete properties I realized that methods like destroy(), restore() and kill() are exactly the same among several controllers. Therefore I am trying to put themn in a trait and use it from diferent Controllers.
My code is as follows:
ProfilesController.php
<?php
namespace App\Http\Controllers;
use App\Profile;
class ProfilesController extends Controller
{
public function destroy(Profile $profile)
{
Profile::del($profile, 'profiles');
return redirect()->route('profiles.index');
}
public function trashed()
{
Profile::trash('Profile');
}
}
Profile.php (model)
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Profile extends Model
{
protected $fillable = ['user_id', 'role_id', 'title', 'subtitle', 'slug', 'birthday', 'about'];
use SoftDeletes, Helpers, commonMethods;
public function getRouteKeyName()
{
return 'slug';
}
// ... more code here
}
trait file: commonMethods.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
use App\Profile;
use Session;
trait commonMethods
{
public static function del($element, $page_name)
{
$element->delete();
Session::flash('success', $element . ' successfully deleted!');
}
public static function trash($model)
{
$total = $model::onlyTrashed()->get();
$total_tr = count($total);
$all_tr = $model::all();
return view('partials.templates.trashed', compact('total', 'total_tr', 'all_tr'));
}
// ...more code here
}
The problem:
I try to visit the view "Trashed" that will list all elements "softdeleted" but not "killed", the method.
I pass the $model variable with the method trash($model)
I get the following error:
Class App/Profile does not found. Try to call App/Profile
I have debugged and the $model variable contains exactly what I need, the string 'Profile' which is what I need to build the Query:
$total = Profile::onlyTrashed()->get();
This query works while in the ProfilesController, but does not work while in a trait, since the model class is not found.
Any idea how could I make it work?
I am using Laravel 6.
If you need to use a class as a string you will want to use its full name. 'App\Profile' instead of 'Profile'.
$model = 'Profile';
new $model; // will use `\Profile`
$model = 'App\Profile';
new $model; // will use '\App\Profile';
In your controller( ProfilesController ) write :
use App\Profile;
In your model write :
use App\commonMethods;

Argument 1 passed to Illuminate\Database\Eloquent\Relations\HasOneOrMany::save() must be an instance of Illuminate\Database\Eloquent\Model

I am pretty new to Laravel and I am trying to add the post, create by a user into the database. But when I do so, following error comes:
Argument 1 passed to Illuminate\Database\Eloquent\Relations\HasOneOrMany::save()
must be an
instance of Illuminate\Database\Eloquent\Model, string given,
called in C:\xampp\htdocs\lar\app\Http\Controllers\PostController.php on line
25 and defined
User model:
<?php
namespace App;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
class User extends Model implements Authenticatable
{
use \Illuminate\Auth\Authenticatable;
public function posts()
{
return $this->hasMany('App\Post');
}
}
Post Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function user()
{
return $this->belongsTo('App\User') ;
}
}
PostController:
<?php
namespace App\Http\Controllers;
use App\Post;
use Illuminate\Http\Request;
class postController extends Controller
{
public function postCreatePost(Request $request){
// Validation
$post = new Post();
$post->$request['body'];
$request->user()->posts()->save('$post');
return redirect()->route('dashboard');
}
}
Post Route:
Route::post('/createpost',[
'uses' => 'PostController#postCreatePost',
'as'=>'post.create'
]);
Form action:
<form action="{{route('post.create')}}" method="post">
Please tell me how to fix this.. How to fix this?
Thank you in advance.. :)
I think what you want is this:
<?php
namespace App\Http\Controllers;
use App\Post;
use Illuminate\Http\Request;
class postController extends Controller
{
public function postCreatePost(Request $request){
// Validation
$post = new Post();
// here you set the body of the post like that
$post->body = $request->body;
// here you pass the $post object not as string
$request->user()->posts()->save($post);
return redirect()->route('dashboard');
}
}
You need to pass the $post object as an object to the save method. You was doing this: $user->posts()->save('$post') when you need to do this: $user->posts()->save($post).
Hope it helps.

Resources