Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Приветствую!
Есть:
class Model extends Eloquent {
public function prototypes()
{
return $this->belongsToMany('Prototype');
}
public function scopeAnalogs()
{
return $query->where(??????????????);
}
}
class Prototype extends Eloquent {
public function models()
{
return $this->belongsToMany('Model');
}
}
Требуется из Model получить все модели у которых прототипы как у текущей модели.
Пример:
М1 - П1
М1 - П2
М2 - П1
М2 - П3
М3 - П5
М4 - П2
М5 - П6
Должны получить:
М2
М4
Подскажите решение.
Не в сети
Не в сети
Все сложнее связь многие ко многим, и получить надо Models
Schema::create('prototypes', function($table)
{
$table->increments('id');
$table->string('name');
$table->timestamps();
});
Schema::create('models', function($table)
{
$table->increments('id');
$table->string('name');
$table->timestamps();
});
Schema::create('model_prototype', function($table)
{
$table->increments('id');
$table->integer('prototype_id');
$table->integer('model_id');
$table->timestamps();
});
Не в сети
Как я понимаю надо получить:
Все prototype_id из model_prototype где model_id = $this->model_id
Затем все model_id из model_prototype где prototype_id в списке полученном ранее
Затем уже получить все модели model_id которых в списке полученном в предыдущем шаге.
Не в сети
Заполняем базу тем что дано в задаче
$data = array(
'M1' => array('P1', 'P2'),
'M2' => array('P1', 'P3'),
'M3' => array('P5'),
'M4' => array('P2'),
'M5' => array('P6')
);
foreach($data as $model => $types){
$mObj = Model::firstOrCreate(array('name' => $model));
$tmp = array();
foreach($types as $type){
$tObj = Prototype::firstOrCreate(array('name' => $type));
$tmp[] = $tObj->id;
}
$mObj->prototypes()->sync($tmp);
}
Находим что нужно для записи с именем М1
$current = 'M1';
$mCurrentObj = Model::firstOrNew(array('name' =>$current));
$pCurrent = $mCurrentObj->prototypes()->get()->lists('name');
print_r($pCurrent);
$mOut = array();
if(!empty($pCurrent)){
foreach(Prototype::whereIn('name', $pCurrent)->get() as $pObj){
$mFind = $pObj->models()->where('model_prototype.model_id', '!=', $mCurrentObj->id)->get();
$mOut = array_merge($mOut, $mFind->lists('name'));
}
$mOut = array_unique($mOut, SORT_STRING);
}
print_r($mOut);
Время, качество, цена - выбирай любые 2
Не в сети
Евгений, привет! Хотелось одним запросом. Вот что с утра на свежую голову вышло:
public function analogs()
{
return DB::table('models')
->where('id', '!=', $this->id)
->whereIn('id', function($query)
{
$query->select('model_id')
->from('model_prototype')
->whereIn('prototype_id', function($query)
{
$query->select('prototype_id')
->from('model_prototype')
->where('model_id', '=', $this->id);
});
})
->get();
}
Осталось сделать чтоб возвращало коллекцию объектов Model
Изменено flatter (09.05.2014 09:24:49)
Не в сети
Хотелось одним запросом.
Вот только одно мне интересно. Я подумываю что Субд MySql. Если я прав, то я расстрою. Запрос который уходит, технически один. А вот на уровне субд он не один, их подмножество происходит. И никаких индексов по этому запросу быть не может. Так что чаще всего это не оправдано. Хотя как сказал мне один человек: "В такой запрос меньше шансов что вкрадется ошибка из-за лишнего звена (php)". Но по факту двумя запросами по индексу этот запрос в разы легче для базы.
Не в сети
Но по факту двумя запросами по индексу этот запрос в разы легче для базы.
т.е. если сделать 3 запроса:
1. Все prototype_id из model_prototype где model_id = $this->model_id
2. Все model_id из model_prototype где prototype_id в списке полученном в шаге 1
3. Все модели model_id которых в списке полученном в шаге 2
То это будет эффективнее?
Не в сети
Ruzarh прав, два SELECT (не JOIN) в одном «запросе» это на самом деле два запроса с небольшими оговорками, так что лучше разделить их, код будет понятней, да и отладить проще.
Но не обязательно делать 3 запроса, хватит и двух — сначала получить все прототипы текущей модели, с которыми далее нужно искать другие модели (= $protoIDs). Затем второй запрос:
sqlSELECT m.* FROM models m JOIN model_prototypes mp ON mp.prototype_id IN $protoIDs AND m.id = mp.model_id
Не в сети
Страницы 1