Laravel 5.6显示期间多对多关系抛出错误

时间:2018-04-10 01:33:29

标签: php laravel many-to-many

****更新****************************************** *************

我不确定原因,但是将所有内容都移到控制器index()方法中而不是将它放在show()方法中解决了这个问题。不知道它为什么会起作用,但确实如此。

原始问题:

无法弄清楚这里有什么问题,我已经按照文档,尝试过的变体等等......仍然没有运气使这项工作正常运行。

模特A :(幻灯片)

public function carousels() {
    return $this->belongsToMany(Carousel::class)->withTimestamp()
} 

模特B :(轮播)

public function slides() {
    return $this->belongsToMany(Slide::class)->withTimestamp()
} 

数据透视表

--------------------------------------------------
|carousel_id | slide_id | created_at | updated_at|
--------------------------------------------------

来自控制器:

public function show(Carosuel $carousels) {
    $carousels = $carousel->with('slides)->get();

    return view('myView', compact(['carousels']));
}

在下面的转储中,"幻灯片"不在集合的属性对象中;但是,它们属于关系对象。我不确定这是否是正常行为,或者slide数组是否应该在属性对象中。如果是后者,那么如何实现这一目标呢?

$ caousels dump:

Collection {#1320 ▼
  #items: array:20 [▼
    0 => Carousel {#798 ▼
      #fillable: array:4 [▶]
      #connection: "mysql"
      #table: null
      #primaryKey: "id"
      #keyType: "int"
      +incrementing: true
      #with: []
      #withCount: []
      #perPage: 15
      +exists: true
      +wasRecentlyCreated: false
      #attributes: array:7 [▼
        "id" => 1
        "name" => "Prof. Andre Gerlach"
        "category" => "Dr."
        "active" => 0
        "deleted_at" => null
        "created_at" => "2018-04-07 21:10:52"
        "updated_at" => "2018-04-07 21:10:52"
      ]
      #original: array:7 [▶]
      #changes: []
      #casts: []
      #dates: []
      #dateFormat: null
      #appends: []
      #dispatchesEvents: []
      #observables: []
      #relations: array:1 [▼
        "slides" => Collection {#1300 ▼
          #items: array:5 [▼
            0 => Slide {#1023 ▶}
            1 => Slide {#1024 ▶}
            2 => Slide {#1025 ▶}
            3 => Slide {#1026 ▶}
            4 => Slide {#1027 ▶}
          ]
        }
      ]
      #touches: []
      +timestamps: true
      #hidden: []
      #visible: []
      #guarded: array:1 [▶]
    }
    1 => Carousel {#799 ▶}
    2 => Carousel {#800 ▶}

在视图中:

foreach($carousels as $carousel){

    echo $carousel->name;

    foreach($carousel->slides as $slide){
         echo $slide->tag;
    }
}  

这会抛出E_ERROR Invalid argument supplied for foreach() in view

但是,如果我将其转换为数组,则可行。问题是我还需要对结果进行分页。一旦我这样做,幻灯片阵列再次无法访问。

public function show(Carosuel $carousels) {
    // This works - slides are available to me in the view
    $carousels = $carousel->with('slides)->get()->toarray();

    // This DOESN'T work - slides are not available to me in the view
    $carousels = $carousel->with('slides)->paginate(6)->toarray();

    return view('myView', compact(['carousels']));
}

dump as array:

  array:12 [▼
    "current_page" => 1
    "data" => array:6 [▼
      0 => array:8 [▼
        "id" => 1
        "name" => "Prof. Andre Gerlach"
        "category" => "Dr."
        "active" => 0
        "deleted_at" => null
        "created_at" => "Apr 07 2018"
        "updated_at" => "2018-04-07 21:10:52"
        "slides" => array:5 [▼
          0 => array:11 [▶]
          1 => array:11 [▶]
          2 => array:11 [▶]
          3 => array:11 [▶]
          4 => array:11 [▶]
        ]
      ]
      1 => array:8 [▶]
      2 => array:8 [▶]
      3 => array:8 [▶]
      4 => array:8 [▶]
      5 => array:8 [▶]
    ]
    "first_page_url" => "//localhost:3000/admin/carousel/show?page=1"
    "from" => 1
    "last_page" => 4
    "last_page_url" => "//localhost:3000/admin/carousel/show?page=4"
    "next_page_url" => "//localhost:3000/admin/carousel/show?page=2"
    "path" => "//localhost:3000/admin/carousel/show"
    "per_page" => 6
    "prev_page_url" => null
    "to" => 6
    "total" => 20

这里的问题是,在视图中,不再可以访问幻灯片键。引发跟随错误(仅当我使用->paginate()时)。

E_ERROR Trying to get property 'slides' of non-object

我在文档和其他来源中阅读的所有内容都表明这是一个非常基本的操作。对于我的生活,我无法弄清楚为什么它会导致这样的问题。我应该能够通过简单地嵌套foreach来在视图中访问它。

对此的任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

  

在以下转储中,“幻灯片”不在集合的属性对象中;但是,它们属于关系对象。

是的,这是正常的。

这是您遇到问题的地方:

public function show(Carosuel $carousels) {
    // ...
    return view('myView', compact(['carousels']));
}

model binding保留函数中的模型类型。这不是你在这里做的,因为你的路线中没有{id}或其他参数。

删除类型提示并改为调用模型:

public function show() {
    $carousels = Carousel::with('slides')->get();
    return view('myView', compact(['carousels']));
}

如果您想从方法中删除依赖项,则应该在构造函数中执行此操作。

编辑:

虽然我没有看到任何其他问题并且上述解决方案应该有效,但如果->toArray()适合您(但您仍然需要分页),那么您可以只转换基础集合:

public function show() {
    $carousels = Carousel::with('slides')->paginate();
    $carousels->setCollection(collect($carousels->getCollection()->toArray()));
    return view('myView', compact(['carousels']));
}

答案 1 :(得分:0)

你能试试吗?

模特B :(轮播)

public function slides() {
    return $this->hasMany(Slide::class)->withTimestamp();
}