Laravel 5.4 relationship beLongsToMany - php

Hi i need fix returning view. I made relation and its returning array. How i can change this and i am not sure i made good function to relationship. I just trying lerning it i saw many tutorials and i know in Laravel is so kind magic tips to returning.
My function must showing events what user was joining. I think i make it but its returning array and when i try do something like that
#foreach($zapisevents as $zapisevent)
<table class="table">
<th>{{$zapisevent->eventsave->name}}</th>
</table>
#endforeach
i got error:
Property [name] does not exist on this collection instance. (View: /home/mariusz/Pulpit/www/szpital/resources/views/profil/profil.blade.php)
but when i use <th>{{$zapisevent->eventsave}}</th> its returning array.
There is function for joining to event
public function index()
{
$userid = Auth::user();
$zapisevents = User::with('eventsave')->where('id',(Auth::user()->id))->get();
return view('profil.profil', ['userid' => $userid], ['zapisevents' => $zapisevents]);
}
Model User:
public function eventsave()
{
return $this->belongsToMany(HomeModel::class,'save_events','users_id','events_id')->withTimestamps();
}
Model HomeModel <<<
public function usersave()
{
return $this->belongsToMany(User::class,'save_events','events_id','users_id');
}
Its returning:
[{"id":5,"name":"asdasdsa","title":"Wydzial 1","start":"2017-04-04
03:00:00","end":"2017-04-04 07:59:00","created_at":"2017-04-01
18:50:40","updated_at":"2017-04-01
18:50:40","pivot":{"users_id":3,"events_id":5,"created_at":"2017-04-01
18:50:58","updated_at":"2017-04-01
18:50:58"}},{"id":7,"name":"kkkkkkkkkkkkkkkkkkkkkkkk","title":"Wydzial
4","start":"2017-04-01 00:00:00","end":"2017-04-01
23:59:59","created_at":"2017-04-01 19:54:24","updated_at":"2017-04-01
19:54:24","pivot":{"users_id":3,"events_id":7,"created_at":"2017-04-01
19:55:41","updated_at":"2017-04-01 19:55:41"}}]

the
#foreach($zapisevents as $zapisevent)
<table class="table">
<th>{{$zapisevent->eventsave->name}}</th>
</table>
#endforeach
Should ne
#foreach($zapisevents as $zapisevent)
<table class="table">
#foreach($zapisevent->eventsave as $eventSave)
<th>{{$eventsave->name}}</th>
#endForeach
</table>
#endforeach
in you code the name property is being called in a collection of HomeModel but it needs to be called in a model itself

When using arrays, you need to access their properties via their index like this:
$zapisevent->eventsave['name']
as opposed to:
$zapisevent->eventsave->name

Related

Property [path] does not exist on this collection instance

I want to show uploaded pictures of users at my Blade, so I added this:
#foreach($users as $user)
#if($user->photo_id)
<td class="center">
<img src="{{ $user->photos->path }}" width="80">
</td>
#else
<td class="center">
</td>
#endif
#endforeach
But it returns this error:
Exception Property [path] does not exist on this collection instance.
I have already added these relationships to the Models as well:
Photo.php:
public function user()
{
return $this->belongsTo(User::class);
}
User.php:
public function photos()
{
return $this->hasMany(Photo::class);
}
So what is going wrong here ? How can I solve this issue ?
Also when I say: {{ dd($user->photos) }}, it retuns:
Illuminate\Database\Eloquent\Collection {#1231 ▼
#items: []
}
And here is also table photos:
In your User model, you defined one to many relationship. So laravel will return an array of collection.
If you path will not be in array, I suggest you to change the relation to one-to-one.
User.php
public function photos()
{
return $this->hasOne(Photo::class);
}
As far as I understand, you defined your one to many relationship contrariwise.
You're getting multiple photos for a user. So, it is normal to get a collection of photos instead of an instance of photo.
In the result, you don't have path property on photos collection, probably you can handle this error by getting first instance $user->photos->first()->path, but you need to have a clear definition for your model relationship.

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

undefined variable when trying to fetch data from database laravel

Hi I'm having trouble getting data from database after adding a new function inside my controller. Can anyone explain to me this error and what should I do?
Background information: I have 3 different type of tables, personal_infos, user_infos and user_info1s table where personal_infos hasMany user_infos and user_info1s. I am using user_id as a foreign key to link together with personal_infos table
I'm using this video as a reference and want to do something like his end result (see 17.17 of video), but I get this error:
Error: Undefined variable: data
What I want to do:
Route.php
Route::get('/home/{id}', 'HomeController#getData')->name('home');
HomeController
public function getData($id) {
$data['data'] = DB::table('personal_infos')->get()->sortByDesc('upload_time');
if (count($data) > 0) {
return view('home',$data)
->with('test', personal_info::find($id)); // --> after adding this got error
} else {
return view('home');
}
}
Home.blade.php
<table class="table table-bordered">
<tr>
<th><strong><big>Name: </big></strong></th>
</tr>
<td>
<tr>
#foreach($data as $value)
<tr>
<th>{{HTML::link_to_route('home',$value->Name, array($value->id)) }}</th>
</tr>
#endforeach
</tr>
</tr>
</table>
Code that I have now after some changes:
HomeController:
public function getData($id = null){
$data['data'] = DB::table('personal_infos')->orderBy('created_at', 'desc')->get();
return view('home')
->with('personalInfos', $personalInfos)
->with('test', personal_info::find($id));
}
}
home.blade.php
<ul>
#foreach ($personalInfos as $info)
<li>{{ HTML::link_to_route('home', $info->Name, [ $info->id ]) }}</li>
#endforeach
</ul>
Route
Route::get('/home/{id?}', 'HomeController#getData')->name('home');
personal_info model: (don't know if needed but just in case)
class personal_info extends Eloquent
{
protected $fillable = array('Email', 'Name', 'Mobile_No');
protected $table = 'personal_infos';
protected $primaryKey = 'id';
public function user_infos() {
return $this->hasMany('App\user_info','user_id');
}
public function user_info1s() {
return $this->hasMany('App\user_info1','user_id');
}
}
user_info1 and user_info (they are similar so I will just put 1 of them)
class user_info1 extends Eloquent
{
protected $fillable = array('hobby','sport','user_id');
public function personal_infos() {
return $this->belongsTo('App\personal_info', 'user_id', 'id');
}
}
I can tell you're learning Laravel. There are several issues with the code posted in your question. Let's walk through each of these to see if we can improve your understanding.
First, let's take a look at the controller method signature:
public function getData($id)
This method expects an $id parameter defined in the corresponding route. However, if we take a look at the route:
Route::get('/home/(:any)', 'HomeController#getData')->name('home');
...it doesn't properly declare that the URL contains a parameter (the video you're watching is about a very old version of Laravel). As described in the docs, we'll need to change the route signature to include a parameter for $id:
Route::get('/home/{id}', 'HomeController#getData')->name('home');
Next, let's see how the controller method fetches its data:
$data['data'] = DB::table('personal_infos')->get()->sortByDesc('upload_time');
This query fetches all records from personal_infos into a Collection, and then sorts them by upload_time. This is fine, but database engines can usually sort data faster than our PHP application, so we can instruct the DB to sort our data for us:
$data['data'] = DB::table('personal_infos')->orderBy('upload_time', 'desc')->get();
Notice how we changed the call to sortByDesc() on the collection to orderBy() for the database query. Now, the database sorts the results for us, so the collection doesn't need to.
Finally, let's try to fix the error you experience when passing the data to the view. Here's how your controller method currently does it:
if (count($data) > 0) {
return view('home', $data)
->with('test', personal_info::find($id)); // --> after adding this got error
} else {
return view('home');
}
There are a couple problems with the code above:
count($data) will always be greater than zero, because we're setting $data['data'] every time we call the method, so the else block will never execute. This is probably fine because...
...when count($data) equals zero, the controller doesn't pass the view any data, so $data in the view will be undefined.
The view in question uses #foreach to loop through each of the results, so we can simplify the code in the controller method because foreach won't iterate over an empty collection:
$personalInfos = DB::table('personal_infos')->orderBy('upload_time', 'desc')->get();
return view('home')
->with('personalInfos', $personalInfos)
->with('test', personal_info::find($id));
The view will receive two variables from the method above: $personalInfos and $test. I took the liberty of renaming $data['data'] into a more meaningful variable. This becomes very important as the project grows. Here's how we can use the data in the view:
<ul>
#foreach ($personalInfos as $info)
<li>{{ HTML::link_to_route('home', $info->Name, [ $info->id ]) }}</li>
#endforeach
</ul>
The template above outputs an unordered list as shown in the image in the question. The original table contains several row/column nesting errors and will not display the information like the question describes. As we can see, this template loops through each result in $personalInfos. If $personalInfos is empty, the list will not display any items.
If we want our controller method to handle the route with or without an ID, we'll need to tell Laravel that the ID is optional. For the route, a question mark (?) after the parameter makes it optional:
Route::get('/home/{id?}', 'HomeController#getData')->name('home');
Then, we can set a default value for the controller method that handles the route. In this case, we'll use null:
public function getData($id = null)
Of course, after we update this, we'll need to change the method to handle a null $id argument, which we use to fetch a personal_info for the view's $test variable. The question doesn't explain how the view uses $test, so I'll leave this as an exercise to the reader :)
Follow are two ways to pass multiple variables to view:
//Passing variable to view using with Method
return view('home')->with(['test'=>personal_info::find($id),'data'=>$data['data']]);
//Passing variable to view using Associative Array
return view('home', ['test'=>personal_info::find($id),'data'=>$data['data']]);

Laravel Error: Property [id] does not exist on this collection instance. Yet it works on the local server

As mentioned in the title I get the error "Property [id] does not exist on this collection instance." Only when I run the code online here are my relevant codes.
1-EmployeeController (browser tells me that the error is here the second line)
public function show(Employee $employee)
{
$employee = Employee::find ($employee);
$edocument = EDocument::where ('employee_id',$employee->id)->first();
return view ('employee.show')->withEmployee($employee)->withEdocument($edocument);
}
2-show.blade.php
<div class="jumbotron">
<h1>{{$employee->name}} ({{$employee->position}})</h1>
#if (isset($edocument))
Go To Employee Database Page
#else
<p class="lead bg-danger">Employee documents are not uploaded</p>
#endif
Create Employee Contract
if anyone can explain to me this error in more details that would be great also. thanks
ps.. this is my first laravel project (;
You use route model binding in your controller method to get the Employee model. But you also run a find, which would fail since you're passing the model instead of the id. Do as one of the codes shown below and don't mix them.
Do this if you want to use route model binding.
public function show(Employee $employee)
{
$edocument = EDocument::where ('employee_id', $employee->id)->first();
return view ('employee.show')->with(compact('employee', 'edocument'));
}
Do this if you want to pass the employee id and fetch the model in controller.
public function show($employee)
{
$employee = Employee::find($employee);
$edocument = EDocument::where ('employee_id', $employee->id)->first();
return view ('employee.show')->with(compact('employee', 'edocument'));
}
Maybe this can help you. Why don't you pass the information in the controller using -
return view('employee.show', ['employee' => $employee, 'edocument'=>$edocument]);
It worked for me. (Do not have to change anything in the show.blade .php)

Laravel 4 - Access to Table through Relational Models

Edit: typo
I have two Models: Project and Task. Both are relational to each other:
Project.php
class Project extends Eloquent {
public function tasks()
{
return $this->hasMany('Task');
}
Task.php
class Task extends Eloquent {
protected $guarded = [];
public function project()
{
return $this->belongsTo('Project');
}
Through my ProjectsController I pass the necessary Variables to my Projects View, like this:
ProjectsController:
public function index()
{
$projects = Project::with('tasks')->get();
return View::make('projects.index')
->with('projects', $projects);
}
And in my View I loop through every Project to show everything on a table:
Projects List
<table>
<tr>
<th>Id</th>
<th>Titel</th>
<th>Description</th>
<th>Tasks</th>
</tr>
#foreach($projects as $project)
<tr>
<td>{{$project->id}}</td>
<td>{{$project->title}}</td>
<td>{{$project->description}}</td>
<td>{{$project->task}}</td>
</tr>
#endforeach
</table>
As you can see, the last td-Tag, should access data from the tasks table.
I know that the above View does not work. But I want to know in general, how I would go about it, if I want to output the number of tasks, each project has.
Or anything else, that explains, how I can access different tables, through relational Models, in this particular situation.
since you defined the project model with $this->hasMany('Task'); and fetched models with their tasks, you can simply do
{{ $project->task()->count() }}
be sure to call the tasks as if it were a function, instead of a property.

Categories