2013-03-06 1 views
2

Конечно, я могу использовать order_by со столбцами в моей первой таблице, но не со столбцами на второй таблице, потому что результаты являются частичными.Как «order_by» на второй таблице при использовании красноречивого «один ко многим»

Если я использую «соединение», все работает идеально, но мне нужно добиться этого красноречивым. Я делаю что-то неправильно?

Это пример:

//with join 
$data = DB::table('odt') 
    ->join('hdt', 'odt.id', '=', 'hdt.odt_id') 
    ->order_by('hdt.servicio') 
    ->get(array('odt.odt as odt','hdt.servicio as servicio')); 
foreach($data as $v){ 
    echo $v->odt.' - '.$v->servicio.'<br>'; 
} 
echo '<br><br>'; 
//with eloquent 
$data = Odt::get(); 
foreach($data as $odt){ 
    foreach($odt->hdt()->order_by('servicio')->get() as $hdt){ 
     echo $odt->odt.' - '.$hdt->servicio.'<br>'; 
    } 
} 
+0

этот пакет может помочь вам https://github.com/fico7489/laravel-eloquent-join – fico7489

ответ

0

Теперь я вижу, что это было что-то простое! Я должен сделать запрос на втором столе и получить содержимое первой таблицы с помощью функции а.с.() ведьма установить связь «belongs_to»

//solution 
$data = Hdt::order_by('servicio')->get(); 
foreach($data as $hdt){ 
    echo $hdt->odt->odt.' - '.$hdt->servicio.'<br>'; 
} 
1

В вашей модели вам необходимо явно указать соотношение для сортировки по этому полю.

Таким образом, в модели ODT добавить следующее:

public function hdt() { 
    return $this->has_many('hdt')->order_by('servicio', 'ASC'); 
} 

Это позволит второй стол для сортировки при использовании этого отношения, и вы не будете нуждаться в order_by строку в Fluent присоединиться заявление.

+0

это то же самое, потому что он заказывает все пункты найти в строке, независимо друг от друга. (учитывая, что вы имеете в виду функцию campos()) – ebelendez

0

Я бы посоветовал не включать заказ в реляционный метод, как предложил кодивист. Метод, который вы уложили, функционально идентичен предложению кодивиста.

Разница между двумя решениями заключается в том, что в первом случае вы заказываете odt (все результаты) с помощью hdt.servicio. Во втором вы извлекаете odt в его естественном порядке, а затем заказываете каждый odt, содержащий hdt servico.

Второе решение также намного менее эффективно, потому что вы делаете один запрос, чтобы вытащить все odt, а затем дополнительный запрос для каждого odt, чтобы вытащить его hdts. Проверьте профилировщик. Учитывая ваш первоначальный запрос и что вы только извлекаете один столбец, что-то вроде этой работы?

HDT::where('odt_id', '>', 0)->order_by('servico')->get('servico'); 
+0

Возможно, я должен был включить другой столбец в моем примере, но цель состоит в том, чтобы иметь возможность получать содержимое столбцов в обеих таблицах. – ebelendez

0

Ответ прост:

$data = Odt::join('hdt', 'odt.id', '=', 'hdt.odt_id') 
    ->order_by('hdt.servicio') 
    ->get(array('odt.odt as odt','hdt.servicio as servicio')); 

Все, что вы можете делать с Fluent, также можете сделать с Eloquent. Если ваша цель состоит в том, чтобы получить hdts с их odts Тхо, я рекомендовал бы обратный запрос для улучшения читаемости:

$data = Hdt::join('odt', 'odt.id', '=', 'hdt.odt_id') 
    ->order_by('hdt.servicio') 
    ->get(array('hdt.servicio as servicio', 'odt.odt as odt')); 

Оба они делают то же самое.

Чтобы объяснить, почему это работает:

Всякий раз, когда вы звоните статические методы, такие как Posts::where(...), Красноречивый возвращает свободный запрос для вас, точно так же, как и DB::table('posts')->where(...). Это дает вам гибкость при построении любых запросов. Вот пример:

// Retrieves last 10 posts by Johnny within Laravel category 
$posts = Posts::join('authors', 'authors.id', '=', 'posts.author_id') 
    ->join('categories', 'categories.id', '=', 'posts.category_id') 
    ->where('authors.username', '=', 'johnny') 
    ->where('categories.name', '=', 'laravel') 
    ->order_by('posts.created_at', 'DESC') 
    ->take(10) 
    ->get('posts.*');