Laravel:我如何在视图中划分不同类型的同一模型

时间:2016-12-02 22:21:39

标签: laravel laravel-5 eloquent

我有Athlete模型和Evaluation模型。

运动

/**
 * An athlete has an evaluation.
 *
 * @return \Illuminate\Database\Eloquent\Relations\HasOne
 */
public function evaluation()
{
    return $this->hasOne('App\Evaluation');
}

评价

/**
 * An evaluation belongs to an athlete.
 *
 * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
 */
public function athlete()
{
    return $this->belongsTo('App\Athlete');
}

这是我的控制器:

/**
 * Display the specified resource.
 *
 * @param Athlete $athlete
 * @return $this
 */
public function show(Athlete $athlete)
{
    return view('athletes.show')->with(compact('athlete'));
}

在每个Evaluation中,我有一个statusenum

draft
published
revision

运动员只能在任何给定时间进行1次评估。 运动员在任何特定时间只能有1份评估稿。

运动员可以进行多次修改。修订版只是保存新版本时上一次评估的存档版本。

我不确定如何在我的视图中分离出版本。例如,我只希望published版本填充textarea。

<textarea class="form-control evaluation" rows="3" cols="5" id="evaluation" name="comments">
    {{ $athlete->evaluation->comments ?? '' }}
</textarea>

所以我觉得我需要这样的东西:

{{ $athlete->evaluation->comments::where('status', 'published')->first() ?? '' }}

但我知道这是不正确的。

在我的页面某处显示列表中的修订版本也是如此。

@foreach($athlete->evaluation->comments::where('status', 'revision')...

或者我需要在控制器中单独设置这些对象evaluationdraftsrevisions

然后在我的控制器中:

return view('athletes.show')->with(compact('athlete', 'evaluation', 'drafts', 'revisions'));

这似乎是浪费资源,因为我已经拥有了我需要的一切。

感谢您的任何建议!

1 个答案:

答案 0 :(得分:2)

从我看来,你有两个选择。这是一个简单的:

// Athlete.php
// An athlete actually has many evaluations, but with different statuses

public function evaluations()
{
    return $this->hasMany('App\Evaluation');
}


public function getPublishedEvaluationAttribute()
{
    return $this->evaluations->first(function ($evaluation) {
        return $evaluation->status === 'published';
    });
}

然后,在你看来:

{{ $athlete->evaluations->where('status', 'published')->first()->comments ?? '' }}

或者,使用我们刚创建的访问者:

{{ $athlete->publishedEvaluation->comments ?? '' }}

或者,您可以链接关系查询以直接从数据库获取您想要的内容,而不是迭代以检查状态。当您在视图中需要多个状态时,这意味着更多查询,但在应用程序的其他部分可能有意义。

// Athlete.php

public function evaluations()
{
    return $this->hasMany('App\Evaluation');
}


public function publishedEvaluations()
{
    return $this->evaluations()->where('status', 'published');
}

这种方法的问题在于,即使你知道你只有一个,你必须在你的方法中返回一个关系,否则Laravel会抛出异常。这意味着在您的视图中,您必须编写如下内容:

{{ $athlete->publishedEvaluations->first()->comments ?? '' }}

显然,它们都是简化(我强烈建议在尝试访问comments属性之前检查是否存在评估),但希望能引导您走上您想要的路径。