Laravel用户有许多用户类

我想知道以下用例以及在Laravel中实现此目的的最简单,最优雅的方法。

基本上我会有一个用户表

id, name, email, password

我还将创建一个uggestedUser模型,以便向用户建议某个用户想要关注的用户,并说明他们应该关注该用户的原因。

id user_id, suggested_id, reason

在我的用户类上,将这两者关联起来非常简单

    public function suggestedUsers()
    {
        return $this->hasMany(SuggestedUser::class);
    }

所以现在我可以做

$ user->建议用户并获取数据透视表的结果

=> Illuminate\Database\Eloquent\Collection {#1881
     all: [
       App\Models\PartnerSuggestion {#1939
         id: 1,
         user_id: 1,
         partner_id: 86,
         reason: "You liked similar posts",
         created_at: null,
         updated_at: null,
       },
     ],
   }

But what I am actually looking to do is to return a collection of User::class from this instead of the collection of the pivot.

这样当我执行$ user-> suggestedUsers时,我会得到类似这样的信息,包括原因

Illuminate\Database\Eloquent\Collection {#1940
     all: [
       App\Models\User {#1941
         id: 86,
         first_name: "Eugene",
         last_name: "Simonis",
         reason: "You liked similar posts"
       },
       App\Models\User {#1942
         id: 95,
         first_name: "Wilfred",
         last_name: "Stamm",
         reason: "They viewed your profile"

       },
     ],
   }

我的问题是,最干净,最优雅的方法是什么?我是否需要摆脱数据透视表并建立引用自身的关系?我曾经研究过baum之类的软件包,但出于某种原因(最近4年有效),我宁愿不使用软件包

评论
  • qqgsd
    qqgsd 回复

    我设法通过使用多态关系和特征解决了这个问题。

    trait HasSuggestions
    {
        public function suggestions()
        {
            return $this->morphMany(PartnerSuggestion::class, 'user');
        }
    
        public function suggest(Model $suggestedUser)
        {
    
            $suggestion = (new UserSuggestion())->fillSuggestion($suggestedUser)->fill([
                'reason' => 'reason',
            ]);
            $this->suggestions()->save($suggestion);
            return $suggestion;
        }
    }
    

    然后在我的数据库中,而不仅仅是id字段,我使用了morph字段

    $table->morphs('user');
    $table->morphs('suggested_user');
    

    通过使用此特征,我仍然可以获得相同的结果,但是现在我可以在其上添加一个新方法,该方法将使用查询生成器,因此我可以创建很多查询

    例如:

    $user->getSuggested
    $user->getSuggestedByDate
    

    等等

  • York
    York 回复

    在我看来,您使事情变得过于复杂。可能是,您不需要整个模型来解决问题。

    您真正想要实现的是双方都与用户模型建立多对多关系。

    Laravel中的这种关系在以下User模型内部被引用:

    public function usersIsSuggestedTo() {
        return $this->belongsToMany(User::class, 'suggested_user', 'suggested_id', 'user_id');
    }
    
    public function suggestedUsers() {
        return $this->belongsToMany(User::class, 'suggested_user', 'user_id', 'suggested_id');
    }
    

    You also need to create migration for the suggested_user table.

    Then, you are accessing the collection of suggestedUsers with $user->suggestedUsers and the pivot table (this is the table joining them) with $user->suggestedUsers->pivot.

    Getting reason in your queried collection

    You can also append the reason field to your relationship using ->withPivot('reason') on your relationships like following:

    return $this->belongsToMany(User::class, 'suggested_user', 'user_id', 'suggested_id')->withPivot('reason');
    

    --

    当您不需要完整的模型时,就是这种情况。当您将建议的用户表仅用于存储原因字段和关系本身时。

    This link to the official documentation might be helpful for you: https://laravel.com/docs/7.x/eloquent-relationships#many-to-many