如何从多个对象构建流/源?

时间:2016-05-11 13:27:44

标签: php laravel laravel-5

我想在应用程序的首页上构建通知流。现在,我有新闻,会议和演示的模型。我想将这些元素组合成一个对象,可能称为事件,这样我就可以获取最新的5个事件并在首页上显示它们。输出将类似于:

News Article: Submissions open starting April 1
Presentatiion: How to do stuff, the PDF
Meeting: April 15, Foo High School Gymnasium

对象都实现了一个需要getTitle,getBody和getCreationDate的接口,因此每个对象都可以使用这些函数。

我不想简单地合并集合,因为它变得混乱。有没有办法将这些对象组合成一个对象?

2 个答案:

答案 0 :(得分:3)

我会反对@Tadas说的话,并说使用polymorphism,Eloquent可能仍然是最好的选择。这样,您的所有活动都可以在一个表格中,可以轻松选择,然后您的模型可以保存您需要的任何特殊信息。

让您的表格设置如下:

event
    title
    body
    creation_date
    eventable_id
    eventable_type

news
    some_other_field1

meeting
    some_other_field2

你的模特:

class Event extends Model
{
    /**
     * Get all of the owning imageable models.
     */
    public function eventable()
    {
        return $this->morphTo();
    }
}

class News extends Model
{
    /**
     * Get all of the staff member's photos.
     */
    public function events()
    {
        return $this->morphMany('App\Event', 'eventable');
    }
}

class Meeting extends Model
{
    /**
     * Get all of the product's photos.
     */
    public function events()
    {
        return $this->morphMany('App\Event', 'eventable');
    }
}

此方法可以通过几种不同的方式帮助您:

  1. 获取活动非常简单。想要接下来的5个活动吗? Event::where('event_date', '=>', new DateTime('today'))->orderBy('event_date', 'asc')->take(5);
  2. 以可重复使用的方式轻松获取不同型号的即将发生的事件:

    News:whereHas('events', function($query) {
        $query->where('event_date', '=>', new DateTime('today'))->orderBy('event_date', 'asc')->take(5);
    })->get();
    
  3. 您还可以获得继承的好处,您可以在所有模型中使用不同的字段,但基本Event模型可以包含您的所有通用信息。当您需要事件对象中特定于模型的信息时,只需调用$event->eventable-><whatever field you need>

  4. 即可
  5. 无需原始查询。只需继续使用普通的Laravel语法即可。

答案 1 :(得分:1)

似乎是继承的经典案例。您可以创建一个名为Event的模型。

class Event extends Model

然后你提到的课程将扩展事件。

class Article extends Event
class Presentation extends Event
class Meeting extends Event

然后你可以在Event类上创建一个自定义方法。我认为如果你想避免合并集合,在你的情况下编写简单的SQL比使用Eloquent更简单。

public function getUpcomingEvents()
{
    // something like that, you get the idea
    return DB::select('
        (SELECT title, body, CreationDate FROM articles LIMIT 5)
        UNION 
        (SELECT title, body, CreationDate FROM meetings LIMIT 5)
        ORDER BY CreationDate DESC LIMIT 5')->get();
}

这将使您的控制器保持干净和漂亮,模型结构将代表基础逻辑。