Laravel-多态多对多返回为空 [英] Laravel - Polymorphic many-to-many returns empty

查看:65
本文介绍了Laravel-多态多对多返回为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经呆了5个小时了,似乎无法弄清错误.我在Laravel 4.1中使用了多态多对多关系.

I've been at this for 5 hours now and can't seem to figure out the mistake. I'm using Polymorphic Many-to-Many Relations in Laravel 4.1.

一个工作和一个事件都可以有一个标签,我已经相应地设置了东西.但是每当我打电话

A Job and an Event each can have a Tag and I've set up the stuff accordingly. But whenever I call

$job->tags

它返回空.

我有这3个类(BaseModel扩展了Eloquent,名称空间始终是App \ Models,我必须在例如"morphToMany"函数中引用它们,不适用于"use"):

I have these 3 classes (BaseModel extends Eloquent, namespace is always App\Models, I have to reference them in the e.g. "morphToMany" function, doesn't work with "use"):

class Job extends BaseModel {

    public function tags()
    {
        return $this->morphToMany('\App\Models\Tag', 'taggable');
    }
    [...]
}

标记模型:

class Tag extends BaseModel {

    public function jobs(){
        return $this->morphedByMany('\App\Models\Job', 'taggable');
    }

    public function events(){
        return $this->morphedByMany('\App\Models\Event', 'taggable');
    }
[...]
}

事件模型(如会议,研讨会中的事件"-具有自己的命名空间App \ Models以避免冲突):

The Event Model ("event" as in conference, seminar - has own namespace App\Models to avoid conflict):

class Event extends BaseModel {
    [... nothing relevant yet ...]
}

我的JobsController中有(测试用例,ID为14的作业存在)

In my JobsController I have (test case, job with ID 14 exists)

public function show($slug)
{
    $job = Job::find(14);
    return \View::make('jobs.show', ['job' => $job]);
}

和我的app/views/jobs/show.blade.php

and my app/views/jobs/show.blade.php

[...]
echo $job->name;
echo $job->company;
foreach($job->tags as $tag) {
    echo $tag->name;
}
[...]

第一个输出工作正常,并且正确显示了$ job-> name和$ job-> company,因此它正确地从jobs表中读取,但是

The first outputs work just fine and it show the $job->name and $job->company correctly, so it's reading from the jobs table correctly, but

$job->tags

返回空,并且永远不会调用$ tag-> name.我有一个标签和可标记表(MySQL),这是相关行

returns empty AND $tag->name is never called. I have a tags and taggable table (MySQL), here are the relevant lines

taggables (table)
-> id->increments()
-> tag_id->integer()->unsigned()->index
    ->foreign('tag_id')->references('id')->on('tag')
-> taggable_id->integer()->unsigned()->index()
-> taggable_type->string()->index()

tags (table)
-> id->increments()
-> name->string()
-> slug->string()

测试1

当我这样做

$jobs = Job::has('tags')->get();

在我的JobsController.php视图中,它实际上仅返回带有标签的作业,因此我希望它能起作用一点.

in my JobsController.php view it actually only returns the jobs which have tags, so I'm a bit hopeful that it works a little bit.

测试2

但是当我尝试获取标签时,例如在这种index.blade.php情况下

But when I try to get the tags e.g. in this index.blade.php case

foreach($jobs as $job){
    foreach($job->tags as $tag){
        echo $tag->name;
    }
}

它进入$ jobs循环很好,但是没有进入$ job-> tags循环. 在我的标签表中,我有一个数据集

it goes into the $jobs loop just fine, but it doesn't go into the $job->tags loop. In my taggables table I have a dataset

taggables
id: 1
tag_id: 1 (exists)
taggable_id: 14 (via foreign key)
taggable_type: Job

我疯了,不知道问题出在哪里.我想念什么吗?

I'm going nuts, can't figure out where the problem lies. Am I missing something?

推荐答案

更清洁的解决方案

我已经一直在使用扩展Eloquent的BaseModel.然后,模型仅扩展BaseModel,因此可以对Eloquent进行一些更改.然后,我可以使用相同的内容通过一个小的更改就轻松地覆盖Eloquent morphToMany()函数:

I already always used a BaseModel which extends Eloquent. The Models then only extend BaseModel, so I can do some changes to Eloquent, so to say. I can easily then overwrite the Eloquent morphToMany() function, using the same content, with one tiny change:

<?php namespace App\Models;

class BaseModel extends \Illuminate\Database\Eloquent\Model {

    public function morphToMany($related, $name, $table = null, $foreignKey = null, $otherKey = null, $inverse = false)
    {
        $caller = $this->getBelongsToManyCaller();
        $foreignKey = $foreignKey ?: $name.'_id';
        $instance = new $related;
        $otherKey = $otherKey ?: $instance->getForeignKey();
        $query = $instance->newQuery();
        $table = $table ?: str_plural($name);

        // Only Change: MyMorphToMany instead of the standard MorphToMany
        return new \MyMorphToMany(
          $query, $this, $name, $table, $foreignKey,
          $otherKey, $caller, $inverse
        );
    }
[...]
}

由于morphedByMany()函数实际上还调用了morphToMany(),因此对于多态多对多关系,无需重写该函数.然后,我继续复制整个

Since the morphedByMany() function actually also calls morphToMany() there's no need to rewrite that for polymorphic many-to-many relations. I then went on to copy the whole of

vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/MorphToMany.php

app/models/MyMorphToMany.php

仅作一些更改:

<?
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\MorphPivot;

// no namespace, instead call it when extending
// additionally use Illuminate\Database\Eloquent\Relations\MorphPivot;

// Class MyMorphToMany instead of MorphToMany
class MyMorphToMany extends Illuminate\Database\Eloquent\Relations\BelongsToMany {
    [...]
    public function __construct(Builder $query, Model $parent, $name, $table, $foreignKey, $otherKey, $relationName = null, $inverse = false)
    {
        $this->inverse = $inverse;
        $this->morphType = $name.'_type';
        $this->morphClass = $inverse ? get_class($query->getModel()) : get_class($parent);

        // This is the change to cut everything after "\" in the namespaced Class
        $this->morphClass = substr($this->morphClass, strrpos($this->morphClass, '\\') + 1);
        parent::__construct($query, $parent, $table, $foreignKey, $otherKey, $relationName);
    }
    [...]
}

我认为应该这样做.您现在应该可以使用morphToMany('App\Models\Tag', 'taggable');现在可以了解Laravel中的多态多对多关系.

And that should do it, I think. You should now be able to use e.g. morphToMany('App\Models\Tag', 'taggable'); for a polymorphic many-to-many relation in Laravel now.

感谢 https://stackoverflow.com/a/19884991/3347365 作为提示.

以前的评论/解决方案

这很奇怪.当我删除名称空间时,它起作用了!我删除了Job和Tag类的名称空间,因此可以通过

That's weird. When I remove the namespaces, it works! I've removed the namespaces of Job and Tag class, so I can call via

public function tags(){
    return $this->morphToMany('Tag', 'taggable');
}

在工作模型中而不是

public function tags(){
    return $this->morphToMany('App\Models\Tag', 'taggable');
}

它有效!这是错误还是我执行错误?我主要使用PSR-4,但不确定是否与此有关.

and it works! Is this a bug or did I implement something wrongly? I use PSR-4 mostly, but I'm not sure if that has anything to do with it.

这篇关于Laravel-多态多对多返回为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆