I have two Models that I would like to merge into one timeline. I have been able to do this by creating a View in mysql that normalizes and unions the tables. I created a Model for this view, NewsFeed. This works well if I do not want related Comment model. I have gotten close to this by overriding the getMorphClass method on the model. This allows me to get the related comments for the pictures, but not the posts, because when getMorphClass is called the model doesn't have any data.

我对如何解决这个问题的任何方法都持开放态度,不仅仅是我提议的方式,而且我不想从数据库中提取比我必须提取的更多的数据.

NewsFeed

    <?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;
        }
    }

MySQL View

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`;

pictures table

    id
    user_id
    title
    img
    img_width
    img_height
    img_other
    description
    created_at
    updated_at

posts

    id
    user_id
    title
    body
    created_at
    updated_at

推荐答案

你真的很接近你的 idea ,建立一个视图.事实上,如果创建一个实际的表而不是视图,解决方案就会变得非常简单.

使用指向Post类或Picture类的"FeedItem"变形对象,可以将注释直接附加到具有hasMany关系的FeedItem.

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');
    }
}

这个解决方案可能需要对表单进行一些重构,因为您需要 for each 帖子条目和图片条目创建一个FeedItem条目.Picture::created和Post::created的事件侦听器应该做到这一点(http://laravel.com/docs/5.1/eloquent#events).

设置完成后,您可以使用:

FeedItem::with('comments')->orderBy('created_at','desc')->paginate(15);

Laravel相关问答推荐

如何在Laravel中从多行中获取合并数组?

如何计算具有特定 ID Laravel 的行

如何在 Laravel 中将 Select 选项表单插入数据库

Npm run dev 卡在 APP_URL

Laravel查询多对多关系

从 Laravel Session 数组中删除项目

Lumen和 MongoDB?

laravel 控制器中的全局变量

如何在 Laravel 5.5 中扩展 vendor 包服务提供者

在 Laravel 5 中扩展请求类

Laravel 5.5 类型错误:传递给 Illuminate\Auth\EloquentUserProvider::validateCredentials() 的参数 1 必须是实例

PHP 5.5,什么情况下PHP会导致很高的committed memory

在表单中添加一对多 - Backpack laravel

何时在 Laravel 中使用 Repository vs Service vs Trait?

Laravel:自定义或扩展通知 - 数据库模型

Laravel Eloquent - 加入表时防止覆盖值

Laravel Mix 生成字体到另一个目录

使用 Nginx 设置 Laravel

如何使用 Laravel 迁移在 Mysql 列中添加注释

开发中的 Laravel 和视图缓存 - 无法立即看到更改