Laravel - Eloquent:与命名空间的多态关系

时间:2014-02-16 14:03:35

标签: namespaces laravel-4 eloquent polymorphic-associations

我的情况是:日历属于客户或推销员

因为我也有像Event和File这样的类,所以我使用名称空间App \ Models作为我所有的模型类。

所以我建立了多态关系:

在Calender.php中

public function user() {
    return $this->morphTo();
}

在Customer.php和Salesman.php

public function calendars() {
    return $this->morphMany('App\Models\Calendar', 'user');
}

现在我做的时候

$calendar= Calendar::find(1); //calendar from a salesman
$calendar->user; //error here
...

我收到此错误消息:

Symfony \ Component \ Debug \ Exception \ FatalErrorException
Class 'salesman' not found

我注意到'salesman'是低位的,也许这就是问题?

这就是我从Laravels stacktrace

获得的

open:/var/www/cloudcube/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php

// foreign key name by using the name of the relationship function, which
// when combined with an "_id" should conventionally match the columns.
if (is_null($foreignKey))
{
    $foreignKey = snake_case($relation).'_id';
}

$instance = new $related; //HIGHLIGHTED

我在这行之前遇到过类似的错误,当我搞乱命名空间时,所以我猜它与此有关。有什么办法可以告诉morphTo()方法使用正确的命名空间吗?

或者它是导致这个问题的其他原因吗?

也找到了这个解决方案,但似乎无法让它工作: Polymorphic Eloquent relationships with namespaces

1 个答案:

答案 0 :(得分:5)

我找到了一个适合我的解决方案。

我总是定义与正确命名空间的关系,例如在Calendar:

public function events() { return $this->hasMany('App\Models\Event'); }

我的问题包括两个并发症:

  1. $calendar->user() morphTo(...)函数无效,因为我的模型位于命名空间中,而morphTo(...)无法提供此命名空间。

  2. $salesman->calenders()->get()返回并列出空列表,尽管我在数据库中的关系存在。我发现这是因为与查询的绑定。

  3. 1的解决方案:在Calendar中编写自定义morphTo(...)函数以覆盖Laravel之一。我使用Laravels morphTo(...)的来源作为基础。该函数的最终陈述是return $this->belongsTo($class, $id); $class必须是命名空间的类名。我使用了基本的字符串操作来解决这个问题。

    解决方案2.:在Salesman中编写自定义morphMany(...)函数,并让它返回MyMorphMany(...)类似于Polymorphic Eloquent relationships with namespaces描述的内容。

    这里的问题是传递给$query构造函数的MyMorphMany具有错误的(命名空间)绑定。它会查找where user_type = "App\\Models\\Salesman"

    为了解决这个问题,我在getResults()中使用了一个自定义MyMorphMany函数来覆盖默认的Laravels实现,在那里我更改了绑定以使用正确的,未命名的低级别的类名。然后我在getResults()类的get()函数中调用了此MyMorphMany函数。

    我使用$query->getBindings()$query->setBindings()来更正绑定。

    希望这可以节省其他人几天的工作,就像它本可以救我一样:)

相关问题