There is a relationship between the 2 models. And I want to display category name instead of category_id in show.bade.php. I am getting a this error.
Post model
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use App\cat;---- this is my cat model
class post extends Model
{
use HasFactory;
protected $table = 'posts';
protected $fillable = [
'post_name',
'post_content',
'name',
'status',
'file_path',
'slug',
'game_category_id'
];
public function cat(){
return $this->belongsTo(cat::class);
}
cat model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use App\post;------this is my post model
class cat extends Model
{
use HasFactory;
protected $table = 'cats';
protected $fillable = ['name','slug'];
public function post(){
return $this->hasMany(Post::class);
}
There is a relationship between the 2 models. And I want to display category name instead of category_id in show.blade.php. I am getting a this error.
Blade.php
#foreach($posts as $post)
<tr>
<th scope="row">{{$post->id}}</th>
<td><img src="{{asset('img/') . '/' .$post->file_path}}" width="100px " height="50px" class="img_table"></td>
<td>{{$post->post_name}}</td>
<td>{{$post->name}}</td>
<td>
#if(strcmp($post->status , 'Published') == 0)
<div class="btn btn-success">{{$post->status}}</div>
#else
<div class="btn btn-warning">{{$post->status}}</div>
#endif </td>
<td>{{$post->created_at->diffForHumans()}}</td>
<td>{{$post->slug}}</td>
<td>{{$post->cat->name}}</td>
<td><i class="far fa-edit"></i></td>
<td><i class="far fa-trash-alt"></i></td>
</tr>
#endforeach
$post->cat->name is this right way to call cat name instead of category id
Post Controller
namespace App\Http\Controllers;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Models\post;
use Validator;
public function list(){
$posts = Post::with('cat')->get();
$carbon = Carbon::now();
return view('layout.show', compact('posts'),['carbon' => $carbon]);
}
Since Laravel 8 the default namespace for models is App\Models. So use App\cat; should be use App\Models\cat;.
But you don't have to specify that since both post and cat are in the same namespace. You can just get rid of that line and it should still work.
By the way, Laravel's naming convention for models is to use CamelCase. So I'd stick with that unless you have a specific reason not to do so.
you have to change App\cat to App\Models\cat this will work...
and next.. that line you write <td>{{$post->cat->name}}</td> this will occur error,[Attempt to read property "name" on null] you changed to use separate foreach loop..
#foreach($post->cat as cat)
<td>{{$cat->name}}</td>
#endforeach
This will work for you ...
Related
im new to laravel and i want to know how to make a dynamic sidebar.
Right now it looks like this
In my native language it means category - berrys, juice, candy - and each of them goes to a view, where there should be only products who have in the database one of these three in the "category" column.
My question are:
1)Can i do it with a foreach loop?
2)Do i need to make a model and controller for each of them and if i do what functions do i need?
3)How do i show only the produkcts that have the right category
Right now i have:
#foreach($products as $item)
<div class="col-sm-6 col-md-4">
<a href="details/{{$item['id']}}">
<div class="thumbnail">
<img src="images/{{$item['galerija']}}" alt="...">
<div class="caption">
<h3>{{$item['nosaukums']}}</h3>
<p>{{$item['cena']}}</p>
</div>
</div>
</a>
</div>
#endforeach
That shows every product. Do i need something similar?
More details.
In my controller:
function shop()
{
$data= Product::all();
return view('pages.shop',['products'=>$data]);
}
My moddel:
class Product extends Model{
protected $primaryKey = 'id';
public $timestamps = false;
protected $fillable = [
'nosaukums', 'cena', 'kategorija', 'galerija', 'apraksts',
];
}
Yes.
Since it's the same model, you only need one controller with one method (if you follow conventions this would be a show method).
Using a relation.
Due to the fact you're coding in your native language (which I cannot decipher), below example is a way of how you could do it.
P.S. In the case that a product can have more than one categories, you should convert the relation into a Many to Many using a pivot table.
Category model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
public function products(): HasMany
{
return $this->hasMany(Product::class);
}
}
Product model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
public function category(): BelongsTo
{
return $this->belongsTo(Category::class);
}
}
Web.php
Route::get('categories/{category}', [CategoryController::class, 'show'])->name('categories.show');
Sidebar view
Note: You can load $categories using a View Composer.
<div>
#foreach($categories as $category)
<a href="{{ route('categories.show', compact('category')) }}">
{{ $category->name }}
</a>
#endforeach
</div>
Category controller
<?php
namespace App\Http\Controllers;
use App\Models\Category;
class CategoryController extends Controller
{
public function show(Category $category)
{
$products = $category->products;
return view('categories.show', compact('products');
}
}
ErrorException
Trying to get property 'category_name' of non-object (View: D:\xampp\htdocs\e-catalog\resources\views\backend\pages\gmproducts.blade.php)
This is my blade code below.
<tbody>
#foreach($gmproducts as $no => $gm)
<tr>
<td>{{$no+1}}</td>
<td>{{$gm->type}}</td>
<td>{{$gm->gmcategories->category_name}}</td>
<td>{{$gm->gram}}</td>
<td>{{$gm->carat}}</td>
<td>#currency($gm->price)</td>
<td><a class="test-popup-link" href="{{url('p_goldmart/'.$gm->file)}}">Preview</a></td>
<td>
<i class="fa fa-edit"></i>
<i class="fa fa-trash-o"></i>
</td>
</tr>
#endforeach
</tbody>
This is my model Gmcategories & Gmproducts.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Gmcategories extends Model
{
protected $table = "gmcategories";
protected $fillable = ['category_name'];
public function gmproducts()
{
return $this->hasOne('App\Gmproducts');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Gmproducts extends Model
{
use SoftDeletes;
protected $table = "gmproducts";
protected $fillable = ['type', 'category_id', 'gram', 'carat', 'price', 'file'];
protected $dates = ['deleted_at'];
public function gmcategories()
{
return $this->belongsTo('App\Gmcategories');
}
}
This is my controller.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Gmproducts;
use App\Gmcategories;
use File;
class GmproductsController extends Controller
{
public function index()
{
$gmproducts = Gmproducts::orderBy('id', 'desc')->get();
$trash = Gmproducts::orderBy('deleted_at', 'desc')->onlyTrashed()->count();
return view('backend.pages.gmproducts', compact('gmproducts', 'trash'));
}
public function create()
{
$gmcategories = Gmcategories::all();
return view('backend.pages.create', compact('gmcategories'));
}
Just info, I just rename my model and controller. Does it have any effect? Thanks.
// Gmcategories model
public function gmproducts()
{
return $this->hasOne('App\Gmproducts', 'category_id');
}
// Gmproducts model
public function gmcategories()
{
return $this->belongsTo('App\Gmcategories', 'category_id');
}
Your BuildImage model should be
Get the source type of the Building Image.
public function type() {
return $this->hasOne('App\BuildingType',"id","source");
}
And BuildingType Model should be
Get the Building Image that owns the building type.
public function buildingImage()
{
return $this->belongsTo('App\BuildingImage',"source","id");
}
Let's assume, There Is two Table 'empData' & 'district'. 'empData' table contain 'id', 'name', 'empDistrict' ('empDistrict' contain the corresponding id of district) . and 'District' table contain 'id', 'name' of all districts.
Now I want to fetch the student's details including the district name. (Note: In the empDatatable, I contain only district id) How can I achieve this?
My Implementation
My District Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\EmpData;
class District extends Model
{
protected $guarded = [];
public function empdistrict(){
return $this->belongsTo(EmpData::class, 'empDistrict', 'id');
}
}
My EmpData Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\EmpData;
use App\Models\District;
class empDataController extends Controller
{
$data= EmpData::all();
return view('frontend.allusermindata',compact(['data']));
}
My Blade file where I show the data
foreach($data as $user){
<p>Name : {{ $user->empName }}</p>
<p>District : {{ $user->empdistrict()->name}}</p>
}
But I get this error
Trying to get property 'name' of non-object
foreach($data as $user){
<p>Name : {{ $user->empName }}</p>
<p>District : {{ $user->empdistrict->name}}</p>
}
Calling the method returns a BelonsTo class instance. Use laravel magic method by calling it as an attribute.
Further on this question, you'll have performance issues down the line, better load the data in the same query.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\EmpData;
use App\Models\District;
class empDataController extends Controller
{
$data= EmpData::with('empdistrict')->get();
return view('frontend.allusermindata', compact(['data']));
}
this is my model Faculty
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Faculty extends Model { protected $fillable = [ 'name', 'id', 'date_of_birth', 'age', 'qualification', 'religion', 'gender', 'phone_number', 'address', 'blood_group', 'email' ]; }
this is my FacultiesController
namespace App\Http\Controllers;
use App\Faculty;
use Illuminate\Http\Request;
class FacultiesController extends Controller
{
public function show(Faculty $faculty)
{
$faculties = Faculty::where('id',$faculty->id)->first();
return view('Faculties.show',['Faculty'=>$faculties]);
}
}
this is my route web.php
Route::resource('Faculties','FacultiesController');
this is my blade file show.blade.php
<ul>
<li class="list-group-item">{{ $Faculty->name }}</a></li>
</ul>
There are a couple problems here.
First, this is unnecessary:
public function show(Faculty $faculty)
{
$faculties = Faculty::where('id',$faculty->id)->first();
The routing logic already passes the Faculty model to your function, so you're looking it up twice (and you can also simplify such logic by using Faculty::find() instead of where()->first()).
This should work fine:
public function show(Faculty $faculty)
{
return view('Faculties.show',['Faculty'=>$faculty]);
}
If it doesn't, it may be that there's no Faculty model in your database matching that ID.
I know there's a bunch of problems asked about laravel integrity constraint violation, but none of them are Many to Many relationship, which is my case. Basically I have a table Hobi (hobby) and table Siswa (student), and the relationship is many to many since a student can have many hobbies and a hobby can be favored by many students. So here is the code :
This is my model Hobi :
namespace App;
use Illuminate\Database\Eloquent\Model;
class Hobi extends Model
{
protected $table = 'hobi';
protected $fillable = [
'nama_hobi',
];
public function siswa(){
return $this->belongsToMany('App\Siswa', 'hobi_siswa', 'id_hobi', 'id_siswa');
}
}
model Siswa :
namespace App;
use Illuminate\Database\Eloquent\Model;
class Siswa extends Model
{
protected $table = 'siswa';
protected $fillable = [
'nisn',
'nama_siswa',
'tgl_lahir',
'jns_klmin',
'id_kelas',
'id_hobi',
];
public function hobi(){
return $this->belongsToMany('App\Hobi', 'hobi_siswa', 'id_siswa', 'id_hobi')->withTimeStamps();
}
}
A piece of form view code which contained Hobi :
#if($errors->any())
<div class="form-group {{$errors->has('hobi') ? 'has-error' : 'has-success'}}">
#else
<div class="form-group">
#endif
{!! Form::label('hobi', 'Hobi:', ['class'=>'control-label']) !!}
#if(count($hobi_list) > 0)
#foreach($hobi_list as $key => $value)
<div class="checkbox">
<label>{!! Form::checkbox('hobi[]', $value, null) !!}{{$value}}</label>
</div>
#endforeach
#else
<p>Tidak ada pilihan hobi.</p>
#endif
</div>
And finally the controller :
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Siswa;
use App\Telepon;
use App\Kelas;
use App\Hobi;
use Validator;
class SiswaCont extends Controller
{
public function siswa(){
$siswa_list = Siswa::orderBy('nama_siswa', 'asc')->paginate(10);
$jmlh_siswa = Siswa::count();
return view('siswa.ssw', compact('siswa_list', 'jmlh_siswa'));
}
public function create(){
$kelas_list = Kelas::lists('nama_kelas', 'id');
$hobi_list = Hobi::lists('nama_hobi', 'id');
return view('siswa.create', compact('kelas_list', 'hobi_list'));
}
public function store(Request $request){
$input = $request->all();
$validator = Validator::make($input, [
'nisn'=>'required|string|size:4|unique:siswa,nisn',
'nama_siswa'=>'required|string|max:30',
'tgl_lahir'=>'required|date',
'jns_klmin'=>'required|in:L,P',
no_telepon'=>'sometimes|numeric|digits_between:10,15|unique:telepon,no_telepon',
'id_kelas'=>'required',
]);
if ($validator->fails()) {
return redirect('siswa/create')->withInput()- >withErrors($validator);
}
$siswa = Siswa::create($input);
$siswa->hobi()->attach($request->input('hobi'));
return redirect('siswa');
}
}
I'm using pivot table hobi_siswa to contain id_siswa and id_hobi, creating a bridge. Hobi itself in form view is checkbox modeled. The problem is constraint, data Siswa for another column (nisn, nama_siswa, telepon, etc.) are saved, but Hobi not. Any help appreciated.
Use sync method instead of attach which accepts an array.
From the Docs
The sync method accepts an array of IDs to place on the intermediate table. Any IDs that are not in the given array will be removed from the intermediate table. So, after this operation is complete, only the IDs in the given array will exist in the intermediate table.
For example:
$user->roles()->sync([1, 2, 3]);