Search code examples
sqllaravellaravel-8balde

How to select two relational tables in Laravel that select all fields from the first and one field in the second step


I wish you are doing well. This is my controller code and what I want to do. From the defined table of the projects in the database, I will display the values ​​of the 'title', and 'description'. and from the defined table of images, I will show only the first uploaded photo. How can I fetch values ​​from these tables and send them to the blade and display them in it?

class ProjectsController extends Controller
{
 public function gallery()
 {
  $projects =  \App\Models\Project::orderBy('id', 'desc')
  ->join('images', 'projects.id', '=', 'images.project_id')
  ->select('projects.*','images.url')->get();
  
  return view('projects',compact('projects'));
 }}

Design plan I want

But the external result is that it shows a photo steadily.

The result with a still image

This is blade code

<div class="container d-flex flex-column flex-md-row flex-wrap justify-content-around py-2 px-auto mx-auto">
@foreach($project as $data)<div class="containe position-relative col-11 col-md-3 mx-auto mx-sm-1 my-2">
<a href="{{route('projects.show', $data->id)}}">
    <img src="{{ #problem I had# }}" class="d-block w-100 h-auto rounded-4" alt="">
<div class="overlay position-absolute top-0 h-100 w-100 text-white d-flex flex-column text-center justify-content-center rounded-4">
  <h4 class="fw-bold">{{Str::limit($data->title, 20)}}</h4>
  <p>{{Str::limit($data->description, 100)}}</p>
</div>
</a></div>@endforeach
This is the Image Model
class Image extends Model{
use HasFactory;

protected $table = 'images';

protected $fillable = [
        
    'url', 'project_id'
];

public function project()
{
return $this->belongsTo('App\Model\Project', 'project_id');
}}

This is the Project Model

class Project extends Model{
use HasFactory;
use SoftDeletes;
use Activable;

protected $table = 'projects';

protected $fillable = [

    'title',
    'description',
    'content',
    'is_active',
    'status', 
];

protected $casts = [
    'is_active' => 'boolean',
    'created_at' => 'datetime',
];

protected $guarded = [];

public $timestamps = true;

public function images()
{
    return $this->hasMany('App\Model\Image', 'project_id');
}

}

This is the dd test dd($project)

The last dd test ->with('images') dd test


Solution

  • Avoid using joins, use relationships instead. Eager load the images, using with(), for optimal query execution.

    $projects =  Project::orderBy('id', 'desc')
        ->with('images')
        ->get();
    

    Since it is a one to many relationship, you either have to take the first image or loop all the images.

    Take the first image.

    <img src="{{ $project->images->first()->url }}" class="d-block w-100 h-auto rounded-4" alt="">
    

    Iterate through it.

    @foreach($project->images as $image)
        <img src="{{ $image->url }}" class="d-block w-100 h-auto rounded-4" alt="">
    @endforeach