laravel - updateorcreate - Cómo ordenar por un campo de la tabla dinámica de una relación muchos a muchos en Eloquent ORM
updateorcreate laravel (5)
Acabo de encontrar algo en la guía del usuario, aparentemente necesita el método with()
.
De la User-Guide del User-Guide :
De manera predeterminada, solo se devolverán ciertos campos de la tabla dinámica (los dos campos de identificación y las marcas de tiempo). Si su tabla dinámica contiene columnas adicionales, puede buscarlas también utilizando el método con ():
class User extends Eloquent { public function roles() { return $this->has_many_and_belongs_to(''Role'', ''user_roles'')->with(''column''); } }
Entonces puede usar algo similar a esto cuando defina su relación:
$this->has_many_and_belongs_to(''User'')->with(''playcount'');
Ejemplo
Acabo de usar esto para asegurarme de que funciona ...
class Song extends Eloquent {
function users()
{
return $this->has_many_and_belongs_to(''User'')->with(''playcount'');
}
}
class User extends Eloquent {
function songs()
{
return $this->has_many_and_belongs_to(''Song'')->with(''playcount'');
}
}
// My test method
class TestOrm extends PHPUnit_Framework_TestCase {
public function testSomethingIsTrue()
{
foreach(User::find(3)->songs()->order_by(''playcount'')->get() as $song)
echo $song->name, '': '', $song->pivot->playcount, "/n";
echo "/n";
foreach(User::find(3)->songs()->order_by(''playcount'',''desc'')->get() as $song)
echo $song->name, '': '', $song->pivot->playcount, "/n";
}
}
Salida
Jingle Bells: 5
Mary had a little lamb: 10
Soft Kitty: 20
The Catalyst: 100
The Catalyst: 100
Soft Kitty: 20
Mary had a little lamb: 10
Jingle Bells: 5
Nota : No es coincidencia que sin usar order_by()
el resultado aparezca ordenado en orden ascending
por la cuenta de playcount
. Confirmé esto a través de pruebas (ya que aún no sé cómo mostrar consultas en pruebas unitarias), pero probablemente no deberías confiar en este comportamiento.
He estado usando Eloquent ORM desde hace un tiempo y lo sé bastante bien, pero no puedo hacer lo siguiente, mientras que es muy fácil hacerlo en Fluent .
Tengo usuarios con muchas canciones, siendo la tabla intermedia song_user (como debería ser). Me gustaría obtener las mejores canciones de un usuario, a juzgar por el recuento de reproducciones. Por supuesto, el conteo de juegos se almacena en la mesa intermedia.
Puedo hacerlo en Fluent:
$songs = DB::table(''songs'')
->join(''song_user'', ''songs.id'', ''='', ''song_user.song_id'')
->where(''song_user.user_id'', ''='', $user->id)
->orderBy("song_user.play_count", "desc")
->get();
Fácil. Pero quiero hacerlo en Eloquent, que por supuesto no funciona:
$songs = Song::
with(array("song_user" => function($query) use ($user) {
$query->where("user_id", "=", $user->id)->orderBy("play_count", "desc");
}))
Cualquier método que esté disponible en Fluent también debería estar disponible con Eloquent. Quizás esto es lo que estás buscando?
$songs = Song->join(''song_user'', ''songs.id'', ''='', ''song_user.song_id'')
->where(''song_user.user_id'', ''='', $user->id)
->orderBy("song_user.play_count", "desc")
->get();
En su modelo Eloquent puede encadenar la columna orderBy si incluye el nombre de la tabla:
return $this->belongsToMany(''App/Post'')->withTimestamps()->orderByDesc(''posts.created_at'');
He estado haciendo esto (en varias compilaciones) simplemente usando el método de relación como lo has hecho. A menudo uso una columna de ''orden'' en la tabla dinámica y luego hago algo como esto.
$article->tags()->order_by( ''order'')->get();
Esto puede ser ambiguo si tiene columnas llamadas ''orden'' en la tabla de unión. Si es así, debe especificar -> order_by (''article_tag.order''). Y sí, necesita usar -> con () para obtener esa columna en el conjunto de resultados. Como cuestión de estilo, dejaría el with () fuera del método de relación y simplemente devolvería el objeto de relación vainilla.
No estoy seguro si planea mudarse a Laravel 4, pero aquí hay un ejemplo Eloquent para ordenar por campos de tablas pivote:
public function songs() {
return $this
->belongsToMany(''Song'')
->withPivot(''play_count'')
->orderBy(''pivot_play_count'', ''desc'');
}
withPivot
es como el elocuente with
y agregará el campo play_count
de la tabla pivote a las otras teclas que ya incluye. Todos los campos de la tabla dinámica tienen el prefijo pivot
en los resultados, por lo que puede hacer referencia a ellos directamente en orderBy
.
No tengo idea de cómo se vería en Laravel 3, pero tal vez esto lo ayude a orientarlo en la dirección correcta.
¡Aclamaciones!