php - paginar - Dos modelos en una consulta paginada con relaciones cargadas de interés usando Laravel
paginar un arreglo laravel (2)
Aunque no estoy familiarizado con Laravel ni con Eloquent, de hecho, aquí tengo mi opinión sobre esto.
Suponiendo que está obteniendo el resultado de esa vista SQL en $Entries
Según tengo entendido, Eloquent le permite establecer los valores para usted mismo, por lo tanto, algo como esto podría funcionar para usted (no estoy seguro acerca de la sintaxis o el uso para esa materia).
$Collection = [];
foreach( $Entries as $Entry ) {
if( $Entry->type === ''post'' ) {
$Collection[] = new Post($Entry->toArray())->with(''comments'');
}else{
$Collection[] = new Picture($Entry->toArray())->with(''comments'');
}
}
return $Collection;
Tengo dos modelos que me gustaría fusionar en una línea de tiempo. He podido hacer esto creando una Vista en mysql que normaliza y une las tablas. He creado un modelo para esta vista, NewsFeed
. Esto funciona bien si no quiero un modelo de Comment
relacionado. Me he acercado a esto al reemplazar el método getMorphClass
en el modelo. Esto me permite obtener los comentarios relacionados con las imágenes, pero no con las publicaciones, porque cuando se llama a getMorphClass
el modelo no tiene ningún dato.
Estoy abierto a cualquier enfoque sobre cómo resolver esto, no solo de la forma en que lo estoy proponiendo, sino que no quiero extraer más datos de los que tengo de la base de datos.
Noticias
<?php
namespace App/Users;
use App/Pictures/Picture;
use App/Social/Comments/CommentableTrait;
use App/Posts/Post;
use App/Users/User;
use Illuminate/Database/Eloquent/Model;
class UserFeed extends Model
{
use CommentableTrait;
public function user()
{
return $this->belongsTo(User::class);
}
public function getMorphClass(){
if ($this->type == ''post''){
return Post::class;
}
return Picture::class;
}
}
Vista MySQL
CREATE VIEW
`user_feeds`
AS SELECT
`posts`.`id` AS `id`,
`posts`.`user_id` AS `user_id`,
''post'' AS `type`,
NULL AS `name`,
NULL AS `thumbnail`,
`posts`.`body` AS `body`,
`posts`.`updated_at` AS `updated_at`,
`posts`.`created_at` AS `created_at`
FROM
`posts`
UNION SELECT
`pictures`.`id` AS `id`,
`pictures`.`user_id` AS `user_id`,
''picture'' AS `type`,
`pictures`.`name` AS `name`,
`pictures`.`thumbnail` AS `thumbnail`,
`pictures`.`description` AS `body`,
`pictures`.`updated_at` AS `updated_at`,
`pictures`.`created_at` AS `created_at`
FROM
`pictures`;
mesa de fotos
id
user_id
title
img
img_width
img_height
img_other
description
created_at
updated_at
puestos
id
user_id
title
body
created_at
updated_at
Estás realmente cerca de tu idea de construir una vista. De hecho, si crea una tabla real en lugar de una vista, la solución se vuelve bastante simple.
Con un objeto polimorfo ''FeedItem'' que apunta a su clase Post o clase Picture, puede adjuntar los comentarios directamente al FeedItem con una relación hasMany.
class FeedItem extends Model {
use CommentableTrait;
public function feedable()
{
return $this->morphTo();
}
}
class Post extends Model {
public function feeditem()
{
return $this->morphOne(''FeedItem'', ''feedable'');
}
}
class Picture extends Model {
public function feeditem()
{
return $this->morphOne(''FeedItem'', ''feedable'');
}
}
Esta solución puede requerir cierta refactorización en sus formularios, ya que tendrá que crear una entrada FeedItem para cada entrada Post y Picture. Los detectores de eventos para Picture :: created y Post :: created deberían hacer el truco ( http://laravel.com/docs/5.1/eloquent#events ).
Una vez configurado, puedes usar:
FeedItem::with(''comments'')->orderBy(''created_at'',''desc'')->paginate(15);