我想在应用程序的首页上构建通知流。现在,我有新闻,会议和演示的模型。我想将这些元素组合成一个对象,可能称为事件,这样我就可以获取最新的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的接口,因此每个对象都可以使用这些函数。
我不想简单地合并集合,因为它变得混乱。有没有办法将这些对象组合成一个对象?
答案 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');
}
}
此方法可以通过几种不同的方式帮助您:
Event::where('event_date', '=>', new DateTime('today'))->orderBy('event_date', 'asc')->take(5);
以可重复使用的方式轻松获取不同型号的即将发生的事件:
News:whereHas('events', function($query) {
$query->where('event_date', '=>', new DateTime('today'))->orderBy('event_date', 'asc')->take(5);
})->get();
您还可以获得继承的好处,您可以在所有模型中使用不同的字段,但基本Event
模型可以包含您的所有通用信息。当您需要事件对象中特定于模型的信息时,只需调用$event->eventable-><whatever field you need>
无需原始查询。只需继续使用普通的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();
}
这将使您的控制器保持干净和漂亮,模型结构将代表基础逻辑。