不同用户类型的Laravel关系

时间:2017-04-20 11:27:19

标签: php mysql laravel eloquent

我有一个平台,我有用户是商店,他们可以下订单,我有供应商的用户,他们可以查看已下订单。

  

现在我遇到了一些逻辑问题,例如在我的用户类中,我觉得供应商能够做到这一点

Auth::user()->orders

但作为商店的用户也应该能够做到这一点

Auth::user()->orders

我在这里说明了如何做到这一点的一个不好的例子:

class User extends Authenticatable
{
  public function orders()
  {
      return $this->hasMany(Order::class, 'created_by');
  }

  public function alsoHasOrders()
  {
      return $this->hasMany(Order::class, 'fulfilled_by');
  }

}

应该有更好的方法来做到这一点吗?

2 个答案:

答案 0 :(得分:5)

对于初学者,我建议你重新设计你的数据模型。您的用户模型是您的身份验证者,这是它应该关注的全部内容。它不应该是商店或供应商,或其他任何东西。供应商和商店应该是他们自己的“拥有”用户的独特模型。

您目前所做的事情违反了S.O.L.I.D.就像你的问题的大多数答案一样。特别是O或Open for extension,关闭进行修改。例如,如果用户是商店和供应商,该怎么办?如果稍后您添加了分销商类型,该怎么办?你必须回到那个模型并添加更多的if / else语句,更多类型的关系等等......

相反,我会考虑拥有“商店”和“供应商”的角色以及具有用户的独特商店和供应商模型,其中一个或两个可以分配给用户。一旦完成身份验证,您可能已经拥有User对象,因此在此之后您可以使用服务检索基于该用户指定角色的Shop和Supplier信息。

基本实现的一些快速sudo代码:

class ShopService
{
  public function listOrders(User $user)
  {
    if ($user->hasRole('shop')) {
      return Shop::with('orders')->where('user_id', $user->id)->get()
    }

    return null;
  }
}

class SupplierService
{
  public function listOrders(User $user)
  {
    if ($user->hasRole('supplier')) {
      return Supplier::with('orders')->where('user_id', $user->id)->get()
    }

    return null;
  }
}

这意味着您可以通过添加“分发者”角色和DistributerService

来轻松扩展此功能

但是,如果您仍然决定沿着这条路走下去,至少我建议您仍然拥有独特的Shop和Supplier模型,每个模型都扩展了基本用户模型,然后在每个模型中应用相关关系。

例如:

class User extends Authenticatable
{
   ... user stuff
}

class Shop extends User
{
  public function orders()
  {
      return $this->hasMany(Order::class, 'created_by');
  }
}

class Supplier extends User
{
  public function orders()
  {
      return $this->hasMany(Order::class, 'fulfilled_by');
  }
}

答案 1 :(得分:0)

要进行身份验证,请查看使用guard:https://laravel.com/docs/5.4/authentication

至于您的user()->orders想法,我建议user()->fulfilled()user()->supplied()