MN1's avatar
Level 1

Using Laravel to display movie collection DB w filters?

Hi All,

Front-end developer here looking to make a database challenge for myself:

I'm thinking of creating a database of my disc-based movie/tv collection (I have some DVDs, some Blu-Rays, most are movies, some are TV shows) and connecting to some movie-based API to get the duration in minutes and year of release, and display that on a one-page site with sorting functionality and maybe pagination. I suppose I'd still need to indicate manually whether it's a Blu-Ray or DVD, but then ideally someone could see what TV shows I have that are DVDs in reverse alphabetical order, or perhaps what movies I have in Blu-Ray format in ascending minute duration order, etc.

Would Laravel accomplish this? Any ideas on how to get started? I know some PHP and SQL but only on the beginner to low-intermediate level. Any good examples of how to connect to a movie-based API?

Thanks in advance!

0 likes
18 replies
telein's avatar

There is a way to do this by creating a class that extends Illuminate\Database\Eloquent\Relations\Pivot. Though this approach also requires adding some code to the two models that own this pivot so that they use the new Pivot when needed.



There is a way to do this by creating a class that extends Illuminate\Database\Eloquent\Relations\Pivot. Though this approach also requires adding some code to the two models that own this pivot so that they use the new Pivot when needed.

This link discusses the implementation of the Custom Pivot Model: https://github.com/laravel/framework/issues/2093#issuecomment-39154456

use Illuminate\Database\Eloquent\Relations\Pivot;

class SubjectUser extends Pivot {
   // add your relationships back to User and Subject
    public function session() {
         // your relation to session here
    }
}

class Subject extends Eloquent {
    ...
    public function newPivot(Eloquent $parent, array $attributes, $table, $exists) {
        if ($parent instanceof User) {
            return new SubjectUser($parent, $attributes, $table, $exists);
        }
        return parent::newPivot($parent, $attributes, $table, $exists);
    }
}

class User extends Eloquent {
    ...
    public function newPivot(Eloquent $parent, array $attributes, $table, $exists) {
        if ($parent instanceof Subject) {
            return new SubjectUser($parent, $attributes, $table, $exists);
        }
        return parent::newPivot($parent, $attributes, $table, $exists);
    }
}

Now you will have access to that pivot's relationship that have been defined. This is also used in MediaBox HD.

$user->subjects->first()->pivot->session->...

Note: You will not be interacting with this class directly. It is created instead of the default Pivot when the pivot is needed between those 2 models.

EvelynThomas's avatar

A very bold and very interesting idea. If I had that time I would have done the same with a game like Minecraft.

kevinbui's avatar

This is a 9-year-old thread. I happen to have a couple of side projects related books, music, movies and video games so I can suggest a few tips.

Yes, Laravel can achieve this, then and now, and it is even more fun now.

When we work movies, video games, books and music, there are heaps of external APIs to obtain data from, such as https://www.omdbapi.com/. We don't want to rely too much on those external APIs, and you said you want to sort by duration. So it is probably a good idea to just call the API once, save the response to our database, and not having to run it again:

use App\Models\Movie;
use Http;

class MoviesController extends Controller
{
    public function get(Movie $movie)
    {
        if (! $movie->duration || ! $movie->release_year)
        {
            $response = Http::get("http://img.omdbapi.com/?apikey=my_api_key&{$movie->imdb_id}");

            $movie->update([
                'duration' => $response['duration'],
                'release_year' => $response['release_year']
            ]);
        }

        return view('movies.show', compact('movie'));
    }
}

Please or to participate in this conversation.