I am creating a simple inventory system using larvel 8.
I want to join two tables: category
and products
Category table:
id | categoryname |
---|---|
1 | drink |
2 | biscuits |
3 | toy |
Products table:
id | prodname | catid |
---|---|---|
1 | fanta | 1 |
2 | apple juice | 1 |
3 | buildblocks | 3 |
I need the data passing to the table as the below output
id | productname | categoryname |
---|---|---|
1 | fanta | drink |
While running the program I got the error as:
Undefined property: App\Models\Product::$category
Category
class Category extends Model
{
protected $fillable = [
'id',
'catname',
];
public function products()
{
return $this->hasMany('App\Models\Product', 'id', 'catid');
}
}
Products
class Product extends Model
{
protected $fillable = [
'id',
'prodname',
'catid',
];
public function category()
{
return $this->belongsTo('App\Models\Category', 'category', 'id');
}
}
view.blade.php
<html>
<head>
<body>
<tbody>
@foreach ($products as $key => $product)
<tr>
<td>{{ $key }}</td>
<td>{{ $product->prodname }}</td>
<td>{{ $product->category->catname }}</td>
</tr>
@endforeach
</tbody>
</body>
</head>
</html>
Controller
<?php
namespace App\Http\Controllers;
use App\Models\Category;
use App\Models\Product;
use Illuminate\Http\Request;
class ProductController extends Controller
{
public function view()
{
$products = Product::with('category')->get();
$categories = Category::with('product')->get();
return view('product.view')-> with([
'products' => $products,
'categories' => $categories,
]);
}
}
Routes
Route::get('/products', [ProductController::class, 'view']);
CodePudding user response:
You are mistaken in model here is an example change catid to category_id your colum in product table should be category_id in databsse to
In My user table
public function employee()
{
return $this->hasOne(Employee::class, 'user_id', 'id');
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Here is my employee table
public function user()
{
return $this->belongsTo(User::class);
}
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
You have to work on you controller methods look here
public function showEmployee()
{
$emps = User::with('employee');
return view('employee.show_emp', compact('emps'));
}
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Routes like this
Route::resource('showEmployee','EmpController@showEmployee');
Here is an Your solution I am Trying to put my comfort.
Category
use App\Models\Product;
class Category extends Model
{
protected $fillable = [
'id',
'catname',
];
public function products()
{
return $this->hasMany(Product::class, 'catid', 'id');
}
}
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Products
use App\Models\Category;
class Product extends Model
{
protected $fillable = [
'id',
'prodname',
'catid',
];
public function category()
{
return $this->belongsTo(Category::class);
}
}
<iframe name="sif5" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Controller
<?php
namespace App\Http\Controllers;
use App\Models\Category;
use App\Models\Product;
use Illuminate\Http\Request;
class ProductController extends Controller
{
public function view()
{
$products = Product::with('category')->get();
$categories = Category::with('product')->get();
return view('employee.show_emp', compact('products', 'categories'));
}
}
<iframe name="sif6" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Routes
Route::get('products','ProductController@view');
Add these both lines to your both models after namspace one of each For Category
use App\Models\Product;
For Product
use App\Models\Category;
Note: this is untested code
Here i try to solve your problem
CodePudding user response:
The foreign key passed to the relationship is incorrect and the property you are trying to access in the view does not exist.
Please try out the following changes:
Products.php:
public function category()
{
return $this->belongsTo('App\Models\Category', 'catid', 'id');
}
view:
{{ $product->category->categoryname }}
One To Many (Inverse) / Belongs To
CodePudding user response:
Simple follow Laravel conventions and you avoid to your problems in the future.
https://github.com/alexeymezenin/laravel-best-practices#follow-laravel-naming-conventions
Table structure:
categories
id - integer
name - string
products
id - integer
category_id - integer
name - string
Category model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
protected $fillable = ['name'];
public function products()
{
return $this->hasMany(Product::class);
}
}
Product model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = ['name'];
public function category()
{
return $this->belongsTo(Category::class);
}
}
Routes
Route::get('products', [ProductController::class, 'index']);
Controller
<?php
namespace App\Http\Controllers;
use App\Models\Product;
use Illuminate\Http\Request;
class ProductController extends Controller
{
public function index()
{
$products = Product::with('category')->get();
return view('product.index', compact('products'));
}
}
index.blade.php
<table>
<tbody>
@foreach ($products as $product)
<tr>
<td>{{ $product->id }}</td>
<td>{{ $product->name }}</td>
<td>{{ $product->category->name }}</td>
</tr>
@endforeach
</tbody>
</table>