Laravel - 雄辩:与命名空间的多态关系 [英] Laravel - Eloquent: Polymorphic relations with namespace

查看:201
本文介绍了Laravel - 雄辩:与命名空间的多态关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



由于我也有类,如事件和文件,我使用命名空间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-> user; //错误这里
...

我收到此错误消息:

  Symfony \ Component \ Debug \ Exception \ FatalErrorException 
找不到'salesman'

我注意到,'salesman'低套,也许这是问题?这是我从Laravels堆栈跟踪获得的这个

$ b

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

  //使用名称为关系函数,其中
//与_id组合时应通常匹配列。
if(is_null($ foreignKey))
{
$ foreignKey = snake_case($ relation).'_ id';
}

$ instance = new $ related; // HIGHLIGHTED

我在这行之间有一个类似的错误,当我搞砸命名空间时,所以我想这是有关系的。有什么办法可以告诉 morphTo()方法来使用正确的命名空间吗?还是发现这个问题?



还是发现这个问题吗?让它工作:
与命名空间的多态雄辩关系

解决方案

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



我始终定义与正确的命名空间,例如在日历中:



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



我的问题由2个并发症组成:


  1. $ calendar-> user() morphTo(...)函数不起作用,因为我的模型是在一个命名空间,而 morphTo(...)没有办法给这个命名空间。


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


解决方案1.:编写自定义 morphTo(...)在日历中覆盖Laravel之一的函数。我使用Laravels的来源 morphTo(...)作为基础。这个函数的最终语句是 return $ this-> belongsTo($ class,$ id);
$ class 必须是命名空间的类名。我使用基本的字符串操作将其关闭。



解决方案2.:编写自定义 morphMany(...)函数,并让它返回一个 MyMorphMany(...)类似于



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



修复这个我在 MyMorphMany 中使用了一个定制的 getResults()函数,它覆盖了默认的Laravels实现,我改变了绑定使用正确的,没有命名空间的下层,类名。然后我在 MyMorphMany的 get()函数中调用这个 getResults() / code> class



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



希望这可以节省别人几天的工作,像它会救我:)


My situation is: a Calendar belongs to a Customer or Salesman

Because I also have classes like Event and File, I used the namespace App\Models for all my model classes.

so I set up the polymorphic relation:

in Calender.php

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

in Customer.php and Salesman.php

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

Now when i do

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

I get this error message:

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

I noticed that 'salesman' is low cased, maybe this is the problem?

and this is what I get from 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

I had a similar error before on this line, when I was messing with the namespaces, so I guess it has something to do with that. Is there any way I can tell the morphTo() method to use the correct namespace?

Or is it something else causing this issue?

Also found this solution, but can't seem to get it working: Polymorphic Eloquent relationships with namespaces

解决方案

I found a solution that worked for me.

I always define relationships with the correct namespace, for example in Calendar:

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

My problem consisted out of 2 complications:

  1. $calendar->user() with the morphTo(...) function was not working because my models were in a namespace, and morphTo(...) had no way of giving this namespace.

  2. $salesman->calenders()->get() returned and empty list, although my relations in the database were there. I found out this is because of bindings with the query.

Solution for 1. : Writing a custom morphTo(...) function in Calendar to override the one of Laravel. I used the source of Laravels morphTo(...) as a base. The final statement of this function is return $this->belongsTo($class, $id); There $class must be the namespaced class name. I used basic string operations to pull that off.

Solution for 2. : Writing a custom morphMany(...) function in Salesman and letting it return a MyMorphMany(...) similar to what Polymorphic Eloquent relationships with namespaces described.

The problem here is that $query that is passed to the MyMorphMany constructor has the wrong (namespaced) binding. It will look for where user_type = "App\\Models\\Salesman".

To fix this I used a custom getResults() function in MyMorphMany which overrides the default Laravels implementation, there I changed the bindings to use the correct, un-namespaced lower cased, class name. Then I called this getResults() function in the get() function of the MyMorphMany class.

I used $query->getBindings() and $query->setBindings() to correct the bindings.

Hope this saves someone else a few days of work, like it would have saved me :)

这篇关于Laravel - 雄辩:与命名空间的多态关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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