【问题标题】:accessing a parent of a parent relationship laravel访问父关系 laravel 的父级
【发布时间】:2020-08-20 17:09:34
【问题描述】:

我正在 laravel 中构建一个应用程序,其中每个频道都有一些部分,您可以在这些部分中发布线程。我想从线程访问频道。 到目前为止的层次结构是这样的 -渠道 - 部分 ---线程

这是三个模型类

频道


use Illuminate\Database\Eloquent\Model;

class Channel extends Model
{
    public function users(){
        return $this->belongsToMany('App\User');
    }
    public function posts(){
        return $this->hasMany('App\Post');
    }
    public function isSubscribed($id){
        return $this->users()->find($id);
    }
    public function sections(){
        return $this->hasMany('App\Section');
    }
}

部分

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

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

线程

{
    protected $fillable=['title','body','solved'];

    public function solutions(){
        return $this->hasMany('App\Solution');
    }
    public function comments(){
        return $this->hasMany('App\ThreadComment');
    }
    public function section(){
        return $this->belongsTo('App\Section');
    }
    public function arguments(){
        return $this->belongsToMany('App\Argument');
    }
    public function user(){
        return $this->belongsTo('App\User');
    }
    public function reports(){
        return $this->morphTo('App\Report','reportable');
    }
}

我想做的是在线程类中有一个channel() 方法,使我无需每次都执行$thread->section->channel 即可访问通道

【问题讨论】:

  • Laravel 中没有 belongsToThrough 方法(hasManyThrough 的逆方法),因此您可以使用访问器(如下所述),结合 Thread::with('section.channel') ... 执行预加载,或使用添加该关系的外部包,例如 github.com/staudenmeir/belongs-to-through

标签: laravel eloquent relationship


【解决方案1】:

如果你真的想,使用访问器。

public function getChannelAttribute()
{
    return $this->section->channel;
}

【讨论】:

  • 已经尝试但得到了这个LogicException with message 'App/Thread::channel must return a relationship instance.'
  • @gloria00 什么代码会产生该错误?你打电话给$thread->channel 还是$thread->getChannelAttribute()? (因为其中一个会起作用,而另一个不起作用)。请在此处查看他们的文档:laravel.com/docs/7.x/eloquent-mutators#defining-an-accessor
  • 您收到该错误是因为您将函数命名为 channel() 而不是 getChannelAttribute()
【解决方案2】:

如果您对此使用软件包没有问题,请使用https://github.com/staudenmeir/eloquent-has-many-deep。您可以拥有任何级别的关系。

阅读包的使用部分了解详情。

【讨论】:

  • 这个包工作得很好。使用访问器也可以,但这可以保持整体代码干净
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-24
  • 1970-01-01
  • 1970-01-01
  • 2018-11-05
  • 1970-01-01
  • 2015-12-01
  • 2023-01-17
相关资源
最近更新 更多