Nezo96-39273050's avatar

Confused from eloguents (one to many)

So what i want: I want to get movie title from table movies(id) which is connected with table movie_reports by (movie_id). Movie model:

    public function movieReports()
    {
        return $this->hasMany(MovieReport::class);
    }

and MovieReport model:

    public function movie()
    {
        return $this->belongsTo(Movie::class);
    }

schema for movies table:

Schema::create('movies', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('slug');
            $table->string('release');
            $table->string('rating');
            $table->string('url');
            $table->string('dabing');
            $table->string('poster');
            $table->string('trailer');
            $table->timestamps();
        });

and this is schema for movie_reports table:

Schema::create('movie_reports', function (Blueprint $table) {
            $table->id();
            $table->string('user_email');
            $table->string('user_message');
            $table->foreignId('movie_id')->references('id')->on('movies');
            $table->timestamps();
        });

In my MovieReportController i am getting all reports from database here:

$reports = MovieReport::select('id', 'user_email', 'movie_id', 'created_at')->orderBy('id', 'desc')->paginate(15);

but i would like to get actual title istead if movie_id.

If i add new row to movie_reports table it works as i want, it will add current movie id to movie_id collumn and when i click on that id it will show me correct movie which is related to that id (supabase), but how can i get that movie title from table movies ?

Database images

EDIT

When i use tinker to do this there is somethink strange, if i write $report = MovieReport::with('movie')->get(); i get error: Error Class "MovieReport" not found but if i write: $reports = App\Models\MovieReport::with('movie')->get(); i do get all reports with movies linked to. Strange is that i have to write whole path to model: App\Models\model_name but in my other model, Movies i can just write Movies:with('movieReports')->get(); and tinker has no problem with it and it will get all movies

0 likes
3 replies
martinbean's avatar
Level 80

@nezo96-39273050 If you are querying the MovieReport model, then you need to eager load the movie relation it has, to include the related movie with each result:

$reports = MovieReport::with('movie')->orderBy('id', 'desc')->paginate(15);

Now when you’re iterating over reports in your view, you can access the related movie (and its fields):

@foreach($reports as $report)
    <p>Movie name: {{ $report->movie->title }}</p>
@endforeach
1 like
Nezo96-39273050's avatar

@martinbean Thank you this works, but can you explain me what i wrote under EDIT ? why i have to use App\Models\MovieReport::get(); and not just MovieReport ? When i use other model like Movie i can just write Movie::get(); and there is no error like Error Class "MovieReport" not found

JussiMannisto's avatar

You can use the with method to load whatever you need from the movie relation. The relation is retrieved in a separate query, so adding selects manually in the query builder won't work. This works:

$reports = MovieReport::with('movie:id,title')	
	->orderBy('id', 'desc')
	->paginate(15);

If you want to do a single query and manually set the selected columns, you can do a join. That will return all columns in a flat array:

$reports = MovieReport::join('movies', 'movie_reports.movie_id', '=', 'movies.id')	
	->select('id', 'user_email', 'movie_id', 'created_at', 'title')
	->orderBy('movie_reports.id', 'desc')
	->paginate(15);
1 like

Please or to participate in this conversation.