I have trouble with showing related variable in laravel blade
public function GetAll()
{
$news=DB::table('news')->get();
return View('index',['news'=>$news]);
}
In View:
#foreach($news as $new)
...
{{$new->comments()->count()}} Comments
...
#endforeach
Its also doesnt work for any variables of object but working good for first item:
public function Count()
{
$news=News::find(1);
echo $news->comments()->count();
}
public function GetAll()
{
$news = News::with('comments')->get();
return View('index',['news'=>$news]);
}
Use ORM instead of DB.
Related
I am trying to get data from the database and simply display it in the view
public function index()
{
$messages = ProjectInterestedMessages::get();
return view('dashboard/projects-interests', compact($messages));
}
The view
#foreach ($messages as $message)
<h1>{{ $message->first_name }}</h1>
#endforeach
But I am getting this error
compact(): Argument #1 must be string or array of strings, Illuminate\Database\Eloquent\Collection given
The PHP method compact() is a little tricky with its syntax. I make this same mistake all the time.
Change:
return view('dashboard/projects-interests', compact($messages));
to:
return view('dashboard/projects-interests', compact('messages'));
compact() looks for a string representation of the variable.
There are multiple ways you could write this.
using compact where you pass strings representing the variable
public function index()
{
$messages = ProjectInterestedMessages::get();
return view('dashboard/projects-interests', compact('messages'));
}
using ->with
public function index()
{
$messages = ProjectInterestedMessages::get();
return view('dashboard/projects-interests')->with(['messages' => $messages]);
}
With using laravel magic
public function index()
{
$messages = ProjectInterestedMessages::get();
return view('dashboard/projects-interests')->withMessages($messages);
}
Personally, I prefer this form as it avoids pointless variables
public function index()
{
return view('dashboard/projects-interests')
->withMessages(ProjectInterestedMessages::get());
}
You don't need $
return view('dashboard/projects-interests', compact('messages'));
Comparing to tables in Laravel. I have this code in my class (model):
public function table1() {
return $this->hasOne(table1Class::class, 'type', 'bms_id');
}
public function table2() {
return $this->belongsTo(table2Class::class, 'bms_id', 'type');
}
The controller, has something like this:
$type =
DB::table('table2')
->join('table1', 'table1.col_id','table1.col_name')
->select('table2.*', 'table1.*')
->get();
$dataMerge = $dataMerge->merge($type);
In the view, I have:
#foreach($data as $item)
{{$item->type==120}} //this works, no problem
{{$item->col_name}} //this produces nothing!
#endforeach
As you can see, the code stops working when referencing the col_name, any suggestions?
Thanks in advance!
I actually managed to get data from HasManyThrough relations, but when I want to reach the relational data, it throws the error:
Property [publishings] does not exist on this collection instance.
(View: C:\Xampp\htdocs\wave\resources\views\pages\category.blade.php)
As can be seen in the picture down below, I received "publishings" data.
Where I got the error from is this Blade file:
category.blade.php
#foreach ($data->publishings as $item)
<div></div>
#endforeach
Since I have the data, the codes down below can be unnecessary for the solution, but they are there, just in case.
CategoryController.php
public function index($category)
{
$data = Category::where('slug', $category)
->with(['publishings' => function ($query) {
$query->where('slug', '!=', 'placeholder')->latest()->paginate(10);
}])->get();
return view('pages.category')->with('data', $data);
}
Category.php
public function assets()
{
return $this->hasMany('App\Models\Asset');
}
public function publishings()
{
return $this->hasManyThrough('App\Models\Publishing', 'App\Models\Asset');
}
Asset.php
public function category()
{
return $this->belongsTo('App\Models\Category');
}
public function publishings()
{
return $this->hasMany('App\Models\Publishing');
}
Publishing.php
public function asset()
{
return $this->belongsTo('App\Models\Asset');
}
Thanks for your help.
You are passing an Eloquent Collection to the view. If you want to query only the first result, you can use the first() method of the Query Builder instead of get():
public function index($category)
{
$data = Category::where('slug', $category)
->with(['publishings' => function ($query) {
$query->where('slug', '!=', 'placeholder')->latest()->paginate(10);
}])->first();
return view('pages.category')->with('data', $data);
}
If anyone has the same problem and comes across this message, the solution, in my case was actually quite easy. The 3rd line in the picture says:
0 => App\Models\Category
And I was trying to reach the relational data as if the $data is an object. That's why
$data->publishings
thrown the error. Solution is
$data[0]->publishings
Or return only that data from the controller:
return view('pages.category')->with('data', $data[0]);
I have set up two models and made the relationship between them. I want to pass the attributes of the user as well as the user_detail.
I have used a similar code somewhere and it worked perfectly. But it is not working here.
//This is the function in "User.php" model.
public function user_detail(){
return $this->hasOne('App\Profile');
}
//This is the function in "Profile.php" model.
public function user(){
return $this->belongsTo('App\User');
}
//edit function in ProfileController
public function edit($id)
{
$user=User::find($id);
return view('profile.edit')->with('data',$user->user_detail);
}
When I click the edit button in the view, I expect the extract all the details from user table as well as from user_detail table.
I think you should edit your this code a little bit
public function edit($id)
{
$user=User::findOrFail($id);
return view('profile.edit')->with('data',$user);
}
And in your blade file (profile.edit), You can get all details from User and Profile Model.
{{ $data->id }}
{{ $data->user_detail->YOURPARAMETERS }}
The problem is with the relationship naming. Make it camelCase like,
//This is the function in "User.php" model.
public function userDetail(){
return $this->hasOne('App\Profile');
}
//edit function in ProfileController
public function edit($id)
{
$user=User::find($id);
return view('profile.edit')->with('data',$user->userDetail);
}
Reference: https://github.com/laravel/framework/issues/4307#issuecomment-42037712
try using where instead of find and then use with:
$user = User::where('id', $id)->with('user_detail')->first();
return view('profile.edit')->with('data', $user);
In your model:
public function user_detail(){
return $this->hasOne('App\Profile', 'student_no');
}
I am using Laravel 5.2 and using a polymorphic relations table for a feeds page. A feed has pictures, articles, and links that have their own respective models. The controller method that I am using for the feed looks like this:
public function index()
{
$allActivity = Activity::get();
$activity = collect();
foreach($allActivity as $act)
{
$modelString = $act->actable_type;
$class = new $modelString();
$model = $class->find($act->actable_id);
$activity->push($model);
}
return view('feed', compact('activity'));
}
and here is the feed.blade.php view
#foreach($activity as $class)
// Gives me the model name so the correct partial view could be referenced
<?php
$split = explode("\\", get_class($class));
$model = lcfirst($split[1]);
?>
#include("partials.{$model}", [$model => $class])
#endforeach
Because of this setup, I can't get pagination using the method outlined in the Laravel documentation. How could I correctly implement pagination using this setup? Any help would be greatly appreciated.
Access your relation using the actable() relation you should have on your Activity model. It will also help you avoid using find() in the loop like you are which will give you an N+1 issue.
In your activity model you should have an actable method:
class Activity
{
public function actable()
{
return $this->morphTo();
}
}
Then in your view you can lazy load all polymorphic actable relations and pass to the view. You can even keep your view clean and resolve the model name in the map() function:
public function index()
{
$activity = Activity::with('actable')->get()->map(function($activity) {
$activity->actable->className = lcfirst(class_basename($activity->actable));
return $activity->actable;
});
return view('feed', compact('activity'));
}
Then in your view:
#foreach($activity as $model)
#include("partials.{$model->className}", [$model->className => $class])
#endforeach
To run this with pagination it would be:
Controller:
public function index()
{
$activities = Activity::with('actable')->paginate(25);
return view('feed', compact('activities'));
}
View:
#foreach($activities as $activity)
#include('partials.'.lcfirst(class_basename($activity->actable)), [lcfirst(class_basename($activity->actable)) => $activity])
#endforeach