Hello everyone!
I have the following ERD:
6716
In Tour model following relations are defined:
class Tour extends \yii\db\ActiveRecord
{
...
/**
* @return \yii\db\ActiveQuery
*/
public function getStartLocation()
{
return $this->hasOne(Location::className(), ['id' => 'start_location_id']);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getTourLocations()
{
return $this->hasMany(TourLocation::className(), ['tour_id' => 'id']);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getLocations()
{
return $this->hasMany(Location::className(), ['id' => 'location_id'])->viaTable('tour_location', ['tour_id' => 'id']);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getTourSights()
{
return $this->hasMany(TourSight::className(), ['tour_id' => 'id']);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getSights()
{
return $this->hasMany(Sight::className(), ['id' => 'sightseeing_id'])->viaTable('tour_sightseeing', ['tour_id' => 'id']);
}
...
}
My task is to show the list of Tours in Listview depending on the Location or Sightseeing provided in GET request.
First of all I tried to use search model (SearchTour model is default generated by Gii for now) and this approach worked quite well for the request by tour.start_location_id only:
class TourController extends Controller
{
...
/**
* Displays all Tours for single location
* @param string $slug
* @return mixed
*/
public function actionByLocation($slug)
{
$location = Location::findBySlug($slug);
$searchModel = new SearchTour(['start_location_id' => $location->id]);
$toursDataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('by-location', [
'searchModel' => $searchModel,
'dataProvider' => $toursDataProvider,
'location' => $location,
]);
}
...
}
However I can’t figure out the proper and optimal way for displaying using actionByLocation not only the tours by start_location_id, but also if the provided parameter is among the locations linked by tour_location many-to-many junction table.
Moreover in the next step I will be implementing smart filter that may provide one or more sightseeings and ListView output will also need to be adopted for this additional condition.
I started thinking about SqlDataProvider and dynamic SQL building but decided to advice with community first as the chances are high that similar task was already solved by someone of you folks.
Could anyone kindly advise how to better meet above requirements keeping the code clean and with optimal performance?
Thanks a lot in advance!