Display one image from database in laravel - php

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();
}

Related

laravel 8 auth::user collection from tables

I am new to laravel 8 and blade syntax.
I am working on a project where users (agents) can upload apartments.
i have agent table with corresponding model relationship
agent model
public function property()
{
return $this->hasMany(Property::class, property_id, id);
}
property model
public function agents()
{
return $this->belongsTo(Agent::class, agent_id, id);
}
I used breeze to build up my registration and login
i want when an agent is logged in, i will display in his dash board list of his properties.
#foreach(Auth::user()->properties as $property)
#if(($loop->count) > 0)
<td class="py-3 px-2">
<div class="inline-flex space-x-3 items-center">
<span>{{$property->propertyId}}</span>
</div>
</td>
<td class="py-3 px-2">{{$property->building}}</td>
<td class="py-3 px-2">{{$property->rent->name}}</td>
#else
You have not uploaded any apartment
#endif
#endforeach
but i get error "Undefined variable $properties".
Meanwhile, {{ Auth::user()->othernames }} works fine.
AgentController
public function index()
{
return view ('dashboard', [
'agent' => Agent::all(),
'appointment'=>Appointment::all(),
'properties'=>Property::all(),
'schedule'=>AgentSchedule::all()
]);
}
propertyController
public function create()
{
return view('pages.uploadapartment', [
'states'=> State::all(),
'areas'=>Area::all(),
'buildings'=>building::all(),
'buildingtypes'=>BuildingType::all(),
'rentpaymentmethods'=>rentpaymentmethod::all(),
'flattypes'=>flattype::all(),
]);
}
Since you are not using user model to define the relationship!
Your relationship should be like this:
//In your agent model
public function properties()
{
return $this->hasMany(Property::class, 'property_id', 'id');
}
//In property model
public function agent()
{
return $this->belongsTo(Agent::class, 'agent_id', 'id');
}
And when you want properties from a logged-in user, you grab them like this: $properties = Auth::user()->properties;

Many to Many Relationship return trying to get property 'books' of non-object

I am trying to displaying the book a user has favorited, so I think many to many relationships will solve it. So I have 3 tables
Users Table
Books Table
Favorite Table
The Favorite table is the pivot table
Schema::create('favorites', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('book_id')->unsigned();
$table->integer('user_id')->unsigned();
$table->timestamps();
});
In the User Model
public function favorites(){
return $this->hasMany(Favorite::class);
}
In the Book Model
public function favorites()
{
return $this->hasMany(Favorite::class);
}
In my Favorite Model
public function book ()
{
return $this->belongsTo(Book::class);
}
I was able to save to Favorite Column like this
public function favorite($id)
{
Favorite::create([
'book_id' => $id,
'user_id' => Auth::id()
]);
Session::flash('success', "You Favorite a Book");
return redirect()->back();
}
But I am trying to show the Books Favorited
public function mylibrary(){
$user = Auth::user()->books;
// dd($user);
return view('library', compact('user'));
}
In my view, I have this
#foreach($user->books as $mybook)
...
<div class="clearfix"></div>
<p class="authorone">{{ $mybook->author->name }}</p>
<h1 class="book-title">{ $mybook -> title }}</h1>
</div>
#endforeach
You are passing Auth::user()->books to your view, not Auth::user(). You are not passing the User.
In the view you are then trying to use that value as an object:
#foreach ($user->books as $mybook)
Auth::user()->books is most likely returning null since it is not a relation method or an attribute (most likely).
You probably want to pass the User to your view:
view(..., ['user' => Auth::user()]);
Then you would want to access the correct dynamic property for the relationship you want since you aren't showing a books relationship on User.
Your model relationships could use a better setup. There is no Many to Many setup here and you don't need to define a model for the pivot, you are actually avoiding the Many to Many by doing this.
Models:
class User
{
public function books()
{
return $this->belongsToMany(Book::class, 'favorites');
}
}
class Book
{
public function users()
{
return $this->belongsToMany(User::class, 'favorites');
}
}
Controller:
public function favorite($id)
{
Auth::user()->books()->attach($id);
...
}
public function mylibrary()
{
$user = Auth::user()->load('books.author');
return view('library', compact('user'));
}
View:
#foreach($user->books as $mybook)
...
<div class="clearfix"></div>
<p class="authorone">{{ $mybook->author->name }}</p>
<h1 class="book-title">{{ $mybook->title }}</h1>
</div>
#endforeach
I was able to solve it this way
My view
#forelse ($user->favorites as $mybook)
<p class="authorone">{{ $mybook ->book->author-> name }}</p>
<h1 class="book-title">{{ $mybook ->book-> name }}</h1>
#empty
<h2>You haven't Favorited any book</h2>
<div class="text-center">
Return To
</div>
#endforelse
I added this to my user model
public function favorites(){
return $this->hasMany(Favorite::class);
}
public function books()
{
return $this->belongsToMany(Book::class);
}
My controller
public function mylibrary(){
return view('library', ['user' => Auth::user()]);
}

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

Get value from one to many relationship. Laravel

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

Multiple level relationships on Laravel

I have this problem. In Laravel, I have 3 Models, ie:
class Department{
public function coordinations(){
return $this->has_many('Coordination');
}
}
class Coordination{
public function sites(){
return $this->has_many('Site');
}
}
class Site{
public function assets(){
return $this->has_many('FAssets');
}
}
class FAsset{}
I want to display all the asset grouped by Departments. I tryied to do something like:
#foreach($dependencias as $dep)
<tr>
<td colspan="8" style="width:100%">Dependencia: {{ $dep->code }} {{ $dep->description }}</td>
</tr>
#foreach($dep->coordinations()->sites()->assets()->get() as $asset)
...
But I got the "Method [sites] is not defined on the Query class" error. I was looking for the eager loading way but I dont see how it could work with an extra level on the relationships.
Also, I was considering to querying all the assets and filtering the assets given the actual coordination, but I think that this is going to take a lot of time to load...
Thanks in advance
class Deparment{
public function department_assets(){
$assets = array();
foreach($this->has_many('Coordination')->get() as $coordination){
foreach($coordination->sites()->get() as $site){
foreach($site->assets() as $asset)
{
$assets[] = $asset;
}
}
}
return $assets;
}
}
Now we can...
#foreach($dep->department_assets() as $asset)

Categories