I have an Eloquent model that has multiple types of joins that is used to filter out different request to grab the data of movies e.g.: Actors
, Directors
, Writers
, etc...
The joins are necessary because they use unconventional pivot tables. All the queries and eloquent here works and gives the desired returned data - however I'm breaking DRY (Don't Repeat Yourself) principle for each join filters I am creating within a controller.
Here are the code segments that I would like to tweak:
This is a call for all movies by actors:
public function getByActor($where, $limit, $offset)
{
$movieData = array();
$restrictedIdList = $this->getRestrictedIds();
if (empty($restrictedIdList)) {
$restrictedIdList = array(0);
}
$movieData = Movie::
FilterByActorWithInnerJoin(urldecode($where['actorName']))
->selectRaw('movie.*')
->where('movie.status','=','active')
->whereNotIn('movie.id', $restrictedIdList)
->take($limit)
->skip($offset)
->get()
->toArray();
return $movieData;
}
This is for Writers
:
public function getByWriter($where, $limit, $offset)
{
$movieData = array();
$restrictedIdList = $this->getRestrictedIds();
if (empty($restrictedIdList)) {
$restrictedIdList = array(0);
}
$movieData = Movie::
FilterByWriterWithInnerJoin(urldecode($where['writerName']))
->selectRaw('movie.*')
->where('movie.status','=','active')
->whereNotIn('movie.id', $restrictedIdList)
->take($limit)
->skip($offset)
->get()
->toArray();
return $movieData;
}
As you can see the only difference is the FilterBy<filter type join>WithInnerJoin
that I have created within my model.
Here are the joins of the model:
public function scopeFilterByWriterWithInnerJoin($query,$writerName)
{
$query->join('movie_writers as mw', 'mw.movie_id', '=', 'movie.id')
->join('writers as w',function($join) use ($writerName){
$join->on('w.id', '=', 'mw.writer_id')
->where('w.name','like','%'.$writerName.'%');
});
}
public function scopeFilterByActorWithInnerJoin($query,$actorName)
{
$query->join('movie_actors as ma', 'ma.movie_id', '=', 'movie.id')
->join('actors as a',function($join) use ($actorName){
$join->on('a.id', '=', 'ma.actor_id')
->where('a.name','like','%'.$actorName.'%');
});
}
I will have to do the same for producers, directors, etc.
Is there a more efficient way to do this?