2014-03-07 116 views
1

我已經在這裏5個小時了,似乎無法找出錯誤。我在Laravel 4.1中使用了Polymorphic Many-to-Many關係。Laravel - 多態多對多返回空

作業和事件每個都可以有一個標籤,我已經設置了相應的東西。但每當我打電話

$job->tags 

它返回空。

我有這3類(BaseModel延伸口若懸河,命名空間始終是應用程序\模型,我不得不引用它們在如「morphToMany」功能,不與「用」的工作):

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'); 
    } 
[...] 
} 

事件模型( 「事件」,如會議,研討會 - 有自己的命名空間應用\模型,以避免衝突):

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

在我JobsController我已經(測試條件下,ID 14工作存在)

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

和我的應用程序/視圖/職位/ show.blade.php

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

第一輸出工作得很好它顯示$求職> name和$求職>公司正確的,所以它從工作表中正確讀取,但

$job->tags 

返回空並且$標籤 - >名字永遠不會被調用。我有一個標籤,並加標籤表(MySQL的),這裏有相關線路

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

當我在做JobsController.php

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

查看它實際上只返回有標籤的作業,所以我有點希望它有一點作用。

測試2

但是,當我試圖讓標籤例如在這種情況下,index.blade.php

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

它進入$工作循環就好了,但它並沒有進入求職$>標記循環。 在我taggables表我有一個數據集

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

我要瘋了,不能找出問題所在。我錯過了什麼嗎?

回答

2

清潔的解決方案

我已經一直用延伸洋洋灑灑一BaseModel。然後模型只擴展BaseModel,所以我可以對Eloquent做一些改變。我可以很容易地用它覆蓋雄辯morphToMany()功能,使用相同的內容,一個微小的變化:

<?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()沒有必要重寫,對多態許多一對多的關係。然後我去到整個

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中的多態多對多關係。

感謝https://stackoverflow.com/a/19884991/3347365的提示。

以前批註/解決方案

這是奇怪的。當我刪除命名空間時,它起作用!我已經去除了工作和標籤類的命名空間,所以我可以通過

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

的工作模式,而不是調用

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

和它的作品!這是一個錯誤還是我實施錯誤的東西?我主要使用PSR-4,但我不確定這與它有什麼關係。

+0

我認爲這個答案是一個很好的領導,如果你仍然想使用命名空間 - 我會嘗試:http://stackoverflow.com/a/21889381/3347365 –