Get value from one to many relationship. Laravel - php

I have two models Vehicles and Image,
Vehicle hasMany images
public function images(){
return $this->hasMany('App\Image');
}
Image belongsTo a Vehicle:
public function vehicle(){
return $this->belongsTo('App\vehicle');
}
I've retrieved vehicles like:
In Controller:
$ads=ads::orderBy('views','desc')->get();
foreach ($ads as $ad) {
$popularvehicles[]=vehicles::where('id',$ad->Vehicleid)->get()->toArray();
}
View:
#foreach($popularvehicles as $popularvehicle)
#foreach($popularvehicle as $vehicle)
{{$vehicle['vname']}}
#endforeach
#endforeach
Now, I want to retrieve an image that belongs to $vehicle.
I've tried following syntax:
#foreach($popularvehicles as $popularvehicle)
#foreach($popularvehicle as $vehicle)
#foreach($vehicle->image as $image)
<a href="page-product-details.html">
<img src="{{ asset("images/$image->title") }}" alt="{{ $image->title }}" >
</a>
#endforeach
#endforeach
#endforeach
But it is throwing an exception of: Trying to get property of non-object.
What can I do to make it right?

Just a simple example:
You have a model, the model has details in another model.
class Vehicle extends Model
{
protected $fillable = [
'brand',
'etc',
];
public function details()
{
return $this->belongsToMany('App\VehicleDetails');
}
}
And the details model:
class VehicleDetails extends Model
{
protected $fillable = [
'color',
'engine',
];
public function vehicle() {
return $this->belongsTo('App\Vehicle');
}
}
I usually use transformers to return the needed data, but you don't have to. To make use of the hasMany you can call it like this:
return Vehicle::find($vehicleId); // Retrieve the vehicles from the server
// the object retrieved has the details.
$vehicle->details; // then you can use contains the details
// example:
#foreach($vehicle->details as $details)
<a href="page-product-details.html">
<img src="{{ asset("images/$details->imagetitle") }}"
alt="{{ $details->title }}" >
</a>
#endforeach
The returned object contains the details and you can loop trough it how ever you want.
Without more details about how you retrieve the data I can't be more specific.

I can see 2 problems;
Your popularvehicles is an array of arrays
$popularvehicles[]=vehicles::where('id',$ad->Vehicleid)->get()->toArray();
The toArray is turning everything into an array. You no longer have Vehicle objects. https://laravel.com/docs/5.2/collections#method-toarray
Use ->all() instead.
Second Problem
#foreach($vehicle->image as $image)
You want to use $vehicle->images

Related

Display one image from database in laravel

I have two tables in Laravel
jalans
jalan_images
In one id_jalan can be many images, My relations like this
Model Jalan
// Model Jalan
public function jalanImage()
{
// return $this->hasMany('App\JalanImage', 'id_jalan');
return $this->hasMany(JalanImage::class, 'id_jalan');
}
public function firstImage()
{
// return $this->hasOne('App\JalanImage', 'id_jalan');
return $this->hasOne(JalanImage::class, 'id_jalan');
}
Model JalanImage
// Model JalanImage
public function jalan()
{
// return $this->belongsTo('App\Jalan', 'id_jalan', 'id');
return $this->belongsTo(Jalan::class, 'id_jalan', 'id');
}
I want to display data like title, created_at, and the first image in each id_jalan, in my Controller for display data like this
JalanController
// JalanController
public function jalan()
{
$jalan = Jalan::with('firstImage')->orderBy('created_at', 'DESC')->get();
return view('jalan.all', ['jalan' => $jalan]);
// dd($jalan->toArray());
}
In my view, first image from each id_jalan not displayed, my view like this
Blade View
#foreach($jalan as $row)
<div class="post-item clearfix">
<table border="0">
<tr>
<td width="170px">
<a href="#">
<img src="{{ asset('uploads/jalan/' .$row->first_image) }}" alt="" class="img-fluid" width="150px"></td>
</a>
<td>
<h4>{{ $row->title }}</h4>
<i class="icofont-wall-clock"></i> <time>{{ date('d F Y', strtotime($row->created_at)) }}</time>
<p style="color: #F3591F">{{ $row->category }}</p>
</td>
</tr>
</table>
</div>
#endforeach
When I display it with dd($jalan->toArray()); in my controller, the first_image displayed.
How to fix it?
Thank you
You should follow Laravel's (especially Eloquent's) advices and best practices regarding naming convention. That means your gallery_images table should have gallery_id field instead what you have there. Believe or not, that way you'll skip lot of unforced errors and questions. I will leave you answer of how I would do it in your place:
// \App\Gallery::class
class Gallery extends Model
{
public function galleryImages()
{
return $this->hasMany(GalleryImage::class);
}
public function firstGalleryImage()
{
return $this->hasOne(GalleryImage::class);
}
}
// \App\GalleryImage::class
class GalleryImage extends Model
{
public function gallery()
{
return $this->belongsTo(Gallery::class);
}
}
Basically you can set as many as you need methods in model that returns specific relation. In Gallery::class here, you can see I have set one more relation that would return just first image of that gallery. In controller you'd call it with
public function someControllerMethod()
{
$gallery = Gallery::with(['firstGalleryImage'])->first();
// or
$galleries = Gallery::with(['firstGalleryImage'])->get();
}
Now returned object $gallery or collection of $galleries would carry only first image related. In your case (and if you don't want to change names of fields) you need to follow documentation of how to set another model's keys as method's arguments.
you can use Laravel's Eloquent ORM ( Eager Loading ),
here is an example of a single Image(image) and multiple images (media) relationship.
public function media()
{
return $this->hasMany(Media::class, 'foreign_key', 'local_key');
}
public function defaultMedia()
{
return $this->hasOne(Media::class, 'foreign_key', 'local_key');
public function image()
{
return $this->defaultMedia();
}

ErrorException Invalid argument supplied for foreach()

So i was trying to get a full post from the database by id, so when i click this link Lanjutkan Baca <img src="asset/img/icons/double-arrow.png" alt="#"/> it will take me to the url /post/read/{id} and give me the fullpost, but it shows that error,
i search for the same problem and found that that the problem is $blogs variable is an array, but the value it return is not, can anybody show me how to make the method or the view in my code to return an array and show the full post ?
this is my view read.blade.php
#foreach ($blogs as $blog)
<div class="top-meta">{{ Carbon\Carbon::parse($blog->created_at)->format('d-m-Y') }} / di Rakitan</div>
<h3>{{ $blog->name }}</h3>
<p>{!! $blog->message !!}</p>
#endforeach
this is my BlogController.php
public function getFullPost($blog_id) {
$blogs = Blog::all()->where('blogs.id', '=', $blog_id)->first();
return view('post.read')->with(compact('blogs'));
}
this is the model Blog.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Blog extends Model
{
protected $fillable = ['name','message'];
}
and this is the routes
Route::get('/post/read/{blog_id}', 'BlogController#getFullPost')->name('post.read');
Use 'get' method to get all rows with cobditions
public function getFullPost($blog_id) {
$blogs = Blog::where('id', '=', $blog_id)->get();
return view('post.read')->with(compact('blogs'));
}
Add table name in Model to reference in Blog model

Showing Empty after using eloquent un laravel

I have MyRoom.php and TotalCity.php in my project in which each room is categorizes inside a city
so that I did this in MyRoom.php
public function location()
{
return $this->belongsTo(TotalCity::class, 'location_id')->withTrashed();
}
and I did this in TotalCity.php
public function location()
{
return $this->hasMany(MyRoom::class , 'total_city_id')->withTrashed();
}
I have passed id with routes and controller like this
home.blade.php
id)}}">{{ $row->name }}
web.php
Route::get('/city/{id}/rooms/','SiteController#room')->name('room');
SiteController.php
public function room($id) {
$room = TotalCity::find($id)->location;
return view('frontend.pages.rooms', compact('room'));
}
rooms.blade.php
#foreach($room as $row)
<div class="room">
<img src="{{ asset(env('UPLOAD_PATH').'/' . $row['photoi1']) }}"/>
</div>
#endforeach
But this is not showing any rooms in any city while i have stored cities and rooms which comes under particular city in my database.
In the relationship method, you should mention foreign key and owner key as well,
for example in MyRoom.php:
public function location()
{
return $this->belongsTo(TotalCity::class, 'location_id', 'total_city_primary_key')->withTrashed();
}
you can read laravel documentioation for more detail.
foreignKey in TotalCity model is wrong :
public function location(){
return $this->hasMany(MyRoom::class, 'location_id')->withTrashed();
}
I strongly recommend you to change your model's names to City and Room. If you dont want to, make sure in both models you're connecting them to the correct table, you can achieve that using the $table variable in both models, like this:
$table = 'your_table_name';
This will make sure the table is connected right.
Also, you should make a few changes:
In your TotalCity model do this:
public function rooms()
{
return $this->hasMany(MyRoom::class , 'total_city_id')->withTrashed();
}
In your MyRoom model do this:
public function city()
{
return $this->belongsTo(TotalCity::class)->withTrashed();
}
In your SiteController do this:
public function room($id) {
$rooms = TotalCity::find($id)->rooms;
return view('frontend.pages.rooms', compact('rooms'));
}
In your View
#foreach($rooms as $room)
<h2>{{$room->name}}</h2>
<div class="room">
<img src="{{ asset(env('UPLOAD_PATH').'/' . $room['photoi1']) }}"/>
</div>
#endforeach

Laravel multiple controller functions one route

What I'm trying to achieve is post all news by #foreach and between the #foreach do another #foreach to post all comments with the ID from the news post.
I'm unsure on how to pass this ID, to the getNewsComments function.
My controller:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
use App\News;
use App\newsComments;
class newsController extends Controller
{
public function getAllNews(){
$results = News::all();
return view('index')->with('news', $results);
}
}
Route:
Route::get('/', 'newsController#getAllNews');
News model:
class News extends Model
{
// set table
protected $table = 'lg_news';
public function newsComments(){
return $this->hasMany('App\newsCommments');
}
}
Comment model:
class newsComments extends Model
{
// set table name
protected $table = 'lg_newscomments';
}
view
#foreach ($news as $article)
#foreach($news->$newsComments as $comment)
#endforeach
#endforeach
Error:
Undefined variable: newsComments (View:
C:\xampp\htdocs\resources\views\index.blade.php)
Change this line:
return view('index')->with('news', $results);
to
return view('index', ['news' => $results]);
and it probably will work.
PS: with() function will set a session! It will not pass a variable to view.
You don't need multiple routes you just need to have two tables related to each other with 1:N relationship
Article (1) -> Comments (N)
Then you will create a model for each table and create the relation like explained in the Laravel documentation
One to Many relationship in Laravel
Then you will fetch all posts and pass them to the view:
public function getAllArticles()
{
$posts = Post::all();
return view('view-name', $posts);
}
And at the end, create a view and show posts and comments:
#foreach($posts as $post)
{{ $post->title }}
{{ $post->body }}
#foreach($post->comments as $comment)
{{ $comment->title }}
{{ $comment->body }}
#endforeach
#endforeach
Reminder: $post->comments , comments is the method name defined in the model where you create the relationship
Define route at web.php:
Route::get('/', 'ControllerName#getAllArticles');
Go to localhost:8000/ (or to your site domain if the site is hosted) to see the result

laravel eloquent repository query foreign key tables

hi i am using a custom repository and I am getting comfortable with querying one table to retrieve data like so:
public function getAll()
{
// get all logged in users projects order by project name asc and paginate 9 per page
return \Auth::user()->projects()->orderBy('project_name', 'ASC')->paginate(9);
}
and in my controller I simply call
public function __construct(ProjectRepositoryInterface $project) {
$this->project = $project;
}
public function index()
{
$projects = $this->project->getAll();
echo View::make('projects.index', compact('projects'));
}
and my view is as so:
#if (Auth::check())
#if (count($projects) > 0)
#foreach ($projects as $project)
{{ $project->project_name }}
#endforeach
#else
<p>No records, would you like to create some...</p>
#endif
{{ $projects->links; }}
#endif
However within my projects table I have a status_id and a client_id and I want to retrieve records of this these tables with the logged in user but I am not sure how to structure my query, does anyone have any guidance?
According to the laravel documentation, In your project model you can add the following function:
class Project extends Eloquent
{
public function clients()
{
return $this->hasMany(Client::class);
}
}
In your client model you can then add the inverse of the relationship with the function:
class Client extends Eloquent
{
public function project()
{
return $this->belongsTo(Project::class);
}
}
Then you can retrieve the data with a function like:
$clients = Project::find(1)->clients;

Categories