Laravel belongsTo relationship returns empty object - php

post.php
class post extends Model
{
use HasFactory;
public function publisher()
{
return $this->belongsTo('App\Models\User');
}
protected $fillable = ['title','image','price','Describtion','image1','image2','image3','image4','publisher'];
}
Fetchpost.php
class Fetchpost extends Component
{
use WithPagination;
public function render()
{
return view('livewire.fetchpost', ['posts' => post::orderBy('created_at', 'desc')->paginate(10)],);
}
}
fetchpost.blade.php
<div>
#foreach($posts as post)
<img class="rounded" src="{{ $post->publisher->profile_photo_path }}">
<h1>{{ $post->publisher }}</h1>
<h3>{{ $post->title }}</h1>
<p>{{ $post->Description }}</p>
#endforeach
</div>
so what i'm trying to achieve is to show post with publisher profile info like name and profile photo (like facebook), but i am getting error
Trying to get property 'profile_photo_path' of non-object

the problem here is, you are not passing a foreign key explicitly in relationship. so using naming convention for relationship definition, laravel is looking for a publisher_id (relationship method name _ primary key of the parent table) column in your post table. but there's none as your foreign key is publisher only and laravel can't a build a relationship. thus you are getting your error trying to get property of non object. it's a good practice to reference the foreign key in relationship. or make the foreign key using laravel convention.
public function publisher()
{
return $this->belongsTo('App\Models\User', 'publisher');
}

Related

unable to define relationship in laravel 5.7

I have two table as sbj_topics and difficulty_level_sbj_topic so, I want to define relationship b\w them to fetch records, so to make relationship I have done this,
SbjTopic.php:
public function difficulty_level_sbj_topic() {
return $this->hasMany('App\DiffiLvlSbjTopic');
}
And in DiffiLvlSbjTopic.php:
protected $table = 'difficulty_level_sbj_topic';
public function sbj_topics() {
return $this->belongsTo('App\SbjTopic');
}
After that I returned the data to a view as:
$easy = DiffiLvlSbjTopic::where(['subject_id' => $id, 'difficulty_level_id' => 2])->get();
return view('diffi_lvls.show', compact('easy'));
Then in the view I done this:
#foreach($easy as $easy)
{{ $easy->sbj_topics }}
#endforeach
but the page is blank, and when I do this {{ $easy->sbj_topics->sbj_topic_name }} trying to get property of undefined! comes.
The main purpose of creating relationship is to display Subject Topic Name because I have foreign key as sbj_topic_id in difficulty_level_sbj_topic table so if anyone has any other idea to do this without relationship that will be awesome.
Break this down:
SbjTopic - has many difflevels
a difflevel belongs to aSbjTopic
With this understanding, I can see you are getting the difflevels (DiffiLvlSbjTopic). This is actually what you are passing to your blade.
So first off: complete your relationship by specify the foreign keys. i.e:
In the SbjTopics model:
public function difficulty_level_sbj_topic() {
return $this->hasMany('App\DiffiLvlSbjTopic', 'subject_id');
}
with this, you know that in the 'difficulty_level_sbj_topic' you must have the column subject_id.
Now define the reverse relationship in your DiffiLvlSbjTopic model:
public function sbj_topics() {
return $this->belongsTo('App\SbjTopic', 'subject_id');
}
With all these in place in your controller or route all you need to do is fetch the DiffiLvlSbjTopic model properties. For instance:
public function index () {
$easy = DiffiLvlSbjTopic::all();
return view('diffi_lvls.show', compact('easy'));
}
Finally in your view:
#foreach($easy as $difflevel)
<div>{{ $difflevel->sbj_topics->name }} </div>
#endforeach
That's it.
Your both variables should not be $easy it can be something like $easy as $easySingle. And add a loop inside like
#foreach($easy as $easySingle)
foreach ($easySingle->sbj_topics as $topic) {
$topic->property;
}
#endforeach

Connecting two tables in mysql

I have two tables in my database - vnames and vtypes
vtypes have a name field and a id field, vnames have a id field, name field and a vtypes_id field which is a foreign key connected field. It is connected with the id field in vtypes.
I have Vname and Vtype models -
Vname
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Vname extends Model
{
public function vtype() {
return $this->belongsTo('App\Vtype');
}
}
Vtype
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Vtype extends Model
{
public function vname() {
return $this->hasMany('App\Vtype');
}
}
When i delete any column in vtype table i want to delete all the vname columns associated with it.
I found a solution like this -
public function vtypeDestroy($id) {
$vtype = Vtype::find($id);
$vtype->vname()->detach();
$vtype->delete();
Session::flash('success', 'The vtype was successfully deleted');
return redirect('/vtypes');
}
but when i run this function i get an error like this - Call to undefined method Illuminate\Database\Query\Builder::detach()
How can i fix it?
And when i want to get the name of the vtype from vname i am not able to do it. I tried like this
#foreach ($vnames as $vname)
{{ $vname->vtype()->name }}
#endforeach
in a view
But i got an error like this -- Undefined property: Illuminate\Database\Eloquent\Relations\BelongsTo::$name
Please guide me how to fix this two problems which i face now.
Your relation should be as:
Vname Model
class Vname extends Model
{
public function vtype() {
return $this->belongsTo('App\Vtype', 'vtypes_id', 'id');
}
}
Vtype
class Vtype extends Model
{
public function vname() {
return $this->hasMany('App\Vname', 'vtypes_id', 'id');
}
}
Then you can use delete method to delete the relations as:
$vtype = Vtype::find($id);
$vtype->vname()->delete();
$vtype->delete();
And in your view it should be as:
#foreach ($vnames as $vname)
{{ $vname->vtype->name }}
#endforeach
Docs
Please use...
$vtype->vname()->delete();
instead of $vtype->vname()->detach();... Problem solved! For the inverse of it, vname->vtype() you can you dissociate() method... which will set vtype_id to null in vname table. More explanation here
Detach is used for belongsToMany() - belongsToMany() relation... yours is hasMany() - belongsTo().
Also, instead of doing {{ $vname->vtype()->name }}
please do
#foreach ($vnames as $vname)
{{ $vname->vtype->name }}
#endforeach
The reason for this is... when you put the brackets in front of the relation name, it calls a query builder... But here, what you need is the model... So $vname->vtype will give you Vtype Model while $vname->vtype() will give you query builder.

Laravel cannot retrieve data using one to many not working

I have a problem with one to many relationship in Laravel. I cannot retrieve my data from database. My codes are following.
Doctor.php
public function cities()
{
return $this->belongsTo('App\City');
}
City.php
public function doctor()
{
return $this->hasMany('App\Doctor');
}
view
#foreach($doctors as $doctor)
<tr>
<td data-title="ID">{{ $doctor->id }}</td>
<td data-title="Name">{{ $doctor->name }}</td>
<td data-title="Hospital">{{ $doctor->hospital }}</td>
<td data-title="Designation">{{ $doctor->designation }}</td>
<td data-title="City">{{ $doctor->cities->name }}</td> <!-- problem in this line -->
</tr>
#endforeach
When I try to view the data an error has been shown:
ErrorException in 3d7f581c490d492093e6e73f8ebd29525504e56b.php line 46:
Trying to get property of non-object (View: D:\xampp\htdocs\tourisms\root\resources\views\doctors\index.blade.php)
On the belongsTo side of the relationship, when the foreign key name is not specified, it is built using the name of the relationship. In this case, since your relationship is named cities, Laravel will look for the field doctors.cities_id.
If your foreign key is not cities_id, then you need to either change the name of your relationship method, or specify the name of the foreign key:
public function cities() {
return $this->belongsTo('App\City', 'city_id');
}
// or, better:
public function city() {
return $this->belongsTo('App\City');
}
Also, as mentioned by #Christophvh, the naming of your relationships is a little off, but not programmatically incorrect. It makes more sense and is more readable when belongsTo/hasOne relationships are named singular, and belongsToMany/hasMany relationships are named plural.
You are trying to loop a Collection and not an array.
2 solutions:
1)
add ->get(); when you are calling your relationship in your controller
2)
use
#foreach($doctors->all() as $doctor)
instead of
#foreach($doctors as $doctor)
Also a quick tip:
Your naming is not really telling what you are doing. You should swap them around like below. 'A doctor belongs to a city' & 'A city has many doctors'
Doctor.php
public function city()
{
return $this->belongsTo('App\City');
}
City.php
public function doctors()
{
return $this->hasMany('App\Doctor');
}

Query foreign key data from Blade template

I have two models: MenuCategory and MenuItem, I want to display MenuItem data on my blade page along with its MenuCategory. I know its possible to do this by adding it to the return data in my controller however I would like to do it leveraging Eloquent instead, however I receive errors.
Here are my codes:
MenuCategory model
public function items()
{
return $this->hasMany('App\MenuItem');
}
MenuItem model
public function category()
{
return $this->belongsTo('App\MenuCategory');
}
Controller
public function show($id)
{
$item = MenuItem::findOrFail($id);
return view('menu.admin.single', compact('item'));
}
Blade Page
{{ $item->category->name }}
UPDATE:
Table menu_item
id
name
menu_category_id
Table menu_category
id
name
When using all the above I get the following error:
Trying to get property of non-object
This error is due to the naming convention of Eloquent.
Provide the optional foreign key variable in your relationship method to make it work, ie.
$this->belongsTo('App\MenuCategory', 'menu_category_id');
Probably every Item doesn't contain a related category but to make sure you may try something like this, it'll try to retrieve the name only if there is a related category is available:
{{ $item->category ? $item->category->name : 'No Name or empty string' }}
Alternatively you may try something like this:
$item = MenuItem::has('category') // check if there is a related category
->with('category') // if yes then load it with that category
->findOrFail($id);
You used a different foreign key than Laravel expect so explicitly mention it like:
public function category()
{
return $this->belongsTo('App\MenuCategory', 'menu_category_id', 'id');
}

Undefined variable laravel 4.1

I am trying to get data from database and pass values to controller. I am new at laravel and thats the first query. Here is my code:
class Cars extends Eloquent
{
}
FleetController.php
public function index()
{
$fleet = Cars::all()->first()->Description;
return View::make('pages.home')->with('fleet', $fleet);
}
home.blade.php
#extends('layouts.default')
#section('content')
{{ $fleet }}
#stop
The problem is that it shows this at log
Next exception 'ErrorException' with message
'Undefined variable: fleet (View: C:\wamp\www\laravel\app\views\pages\home.blade.php)' in C:\wamp\www\laravel\app\storage\views\7da5cff457f71f3156f90053865b6cb1:2
Stack trace:
You should try using
#if(Session::has('fleet'))
{{Session::get('fleet')}}
#endif
Your '->with()' just flashes the variable to your session. You still need to retrieve it from there though.
Also, you should try creating a model with the same name as your table. If you were to create a model Car that extends Eloquent, it will automatically be linked to your Cars table. Laravel docs:
The lower-case, plural name of the class will be used as the table
name unless another name is explicitly specified.
This part is important as well:
Eloquent will also assume that each table has a primary key column
named 'id'.
Once you got that configured, you'll be able to get the description of a car by simple doing
Car::all()->first()->description;
See also: Laravel docs on eloquent
Update
What should work:
Car.php
class Car extends Eloquent{
//Let's try setting these manually. Make sure they are correct.
protected $table = 'cars';
protected primaryKey = 'id';
}
FleetController.php
public function index()
{
//You have to call the model here, so singular 'Car'.
$fleet = Car::all()->first()->Description;
return View::make('pages.home')->with('fleet', $fleet);
}
home.blade.php
#extends('layouts.default')
#section('content')
//You can use blade's #if as well:
#if(Session::has('fleet'))
{{Session::get('fleet')}}
#endif
#stop

Categories