简体   繁体   中英

Laravel (5.3) Eloquent - Relationship issue

I have the following 3 tables which are normalised:

`Table: TheMovies`
id      | MovieName 
---------------------
1       | Zootopia 
2       | Moana 
3       | Toy Story

`Table: TheGenres`
id      | GenreName 
---------------------
21      | Action 
22      | Animation 
23      | Adventure

`Table: mMoviesGenres`
movieID | genreID 
---------------------
1       | 21 
1       | 23 
2       | 22
2       | 21 
3       | 23
3       | 21

As you can see in the 3rd table a movie has multiple genres, and a genre has multiple movies.

I've created TheMovies and TheGenres models in laravel.

I made sure that the relationship is made inside the models using the following code:

class TheMovies extends Model
{
    public function TheGenres() {
      return $this->belongsToMany('App\TheGenres', 'mMoviesGenres', 'seriesID', 'genreID');
    }
}

class TheGenres extends Model
{
    public function TheGenres() {
      return $this->belongsToMany('App\TheMovies', 'mMoviesGenres', 'genreID', 'seriesID');
    }
}

I've tested everything, and I succeeded displaying a list of genres for a particular movie, and I also succeeded displaying a list of movies for a particular genre.

The actual problem is that I want to display related movies for a particular movie based on genre.

Let's take TheMovies.id = 1 which is similar with TheMovies.id = 3, they are both Action and Adventure as you can see in the third table.

I've found out the query which is needed based on the following post: SQL Query based on other table .

SELECT m2.movieId
FROM mMoviesGenres m1
INNER JOIN mMoviesGenres m2
    ON m1.genreID = m2.genreID
WHERE m1.movieId = 1 AND
      m2.movieId <> 1
GROUP BY m2.movieId
HAVING COUNT(*) >= 2

But I don't know how to transform this query in Eloquent style, and yes I can make a raw query in Eloquent, but I want to make use of the relationship created.

Please give me some advice.

You can try as:

// returns array of genre_ids associate with the TheMovies.id => 1

$genre_ids = TheGenres::whereHas('TheMovies', function($q) {
    $q->where('id', 1);
})->pluck('id')->toArray();

Then use those $genre_ids to fetch the related movies as:

TheMovies::whereHas('TheGenres', function($q) use($genre_ids) {
    $q->whereIn('id', $genre_ids);
})->get();

Update

Assuming you have:

$genre_ids = [21, 23];

then your query can be as:

TheMovies::whereHas('TheGenres', function($q) use($genre_ids) {
    $q->whereIn('genreID', $genre_ids)
        ->groupBy('movieID')
        ->havingRaw('COUNT(DISTINCT genreID) = 2');
})->get();

Note - I have not tested it but you can give it a try.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM