如何从Laravel 5.5中的一对多关系中删除单个(多个)行

时间:2017-12-08 16:08:47

标签: php laravel eloquent one-to-many relation

我在Laravel中有两个模型:标签

class Label extends \Eloquent
{
    protected $fillable = [
        'channel_id',
        'name',
        'color',
    ];

    public function channel()
    {
        return $this->belongsTo('App\Channel');
    }
}

和频道

class Channel extends \Eloquent
{
    protected $fillable = [
        'name',
    ];

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

}

现在删除标签时,我想确保标签属于频道。

这非常好用,因为它甚至是原子的,所以如果标签真的属于频道,那么该行就会被删除。

LabelController:

/**
 * Remove the specified resource from storage.
 *
 * @param  int $id
 * @return \Illuminate\Http\Response
 */
public function destroy($id)
{
    $channel = $this->getChannel();

    Label::where('id', $id)
        ->where('channel_id', $channel->id)
        ->delete();

    return back();
}

我现在的问题是:如何用Eloquent构建它,它是优雅的?类似的东西:

    $channel->labels()->destroy($id);

但关系上没有破坏功能。

更新

我设法朝着正确的方向努力:

$channel->labels()->find($id)->delete();

如果标签分配了正确的channel_id,则会删除带有$ id BUT的标签。如果没有,我得到以下错误,我可以抓住并处理:

FatalThrowableError (E_ERROR) Call to a member function delete() on null

但是,由于Apache是​​线程化的,可能会出现另一个线程在我读取之后更改channel_id的情况。所以除了我的查询之外唯一的方法是运行事务吗?

3 个答案:

答案 0 :(得分:4)

如果您想删除模型的相关项目而不是模型本身,您可以使用以下内容:

$channel->labels()->delete();它将删除与频道相关的所有标签。

如果您只想删除部分标签,可以使用where()

$channel->labels()->where('id',1)->delete();

此外,如果您的关系是多对多,它也将从第三个表中删除。

答案 1 :(得分:0)

您提到过,您首先要检查标签是否有频道。如果是,则应将其删除。

你可以尝试这样的事情:

$label = Label::find($id);
if ($label->has('channel')) {
    $label->delete();
}

答案 2 :(得分:0)

您可以使用findorfail:

$通道 - >标签() - > findOrFail($ ID) - >删除();