【问题标题】:How to Define Relations and Get All Records with Relations in Laravel?如何在 Laravel 中定义关系并获取所有有关系的记录?
【发布时间】:2019-06-20 23:13:36
【问题描述】:

我想定义表之间的关系,不知道哪里出错了。

这些是我的桌子:

用户

-ID -电子邮件 -等级

餐厅

-ID -姓名 -用户身份

菜单

-ID -姓名

restaurant_menu

-restaurant_id -menu_id -价钱

users 表中,字段level 将由我设置两个字:[user][restaurant]

用户模型

public function restaurant(){
    return $this->hasOne(Restaurant::class);
}

餐厅模型

public function menus(){
    return $this->hasMany(Menu::class);
}

菜单模式

public function restaurants(){
    return $this->belongsTo(Restaurant::class);
}

我期待这段代码的输出:

$result = $restaurant->where('id',2)->menus()->get(); 

要记录和关系,但我收到以下错误。

BadMethodCallException 调用未定义的方法 Illuminate\Database\Eloquent\Builder::menus()

我该怎么办?

【问题讨论】:

  • 简写你可以使用$restaurant = Restaurants::find(2)->menus;
  • 还是一样..
  • @MahdiAlikhani 这是因为您的关系设置不正确。正如我在回答中所说,您应该使用 belongsToMany 关系作为您的 Restaurant-vs-Menu 关系。如果您正在努力为您的问题创建适当的表结构,请使用database-design 标签创建一个单独的问题。

标签: php jquery laravel collections eloquent


【解决方案1】:

IN用户模型

public function restaurant(){
   return $this->hasMany(Restaurant::class,'user_id','id');
}

餐厅模型

public function menus(){
   return $this->hasMany(Menu::class,'id','menu_id');
}

菜单模型

public function restaurants(){
  return $this->belongsTo(Restaurant::class);
}

当你看到你的输出时,你需要写

$result = Restaurant::with('menus')->where('id',2)->get(); 

您将获得关系数据。比如哪些餐厅有哪些菜单。

您也可以将其用于您的场景。在您的餐厅模型中使用它

public function menues(){
  return $this>hasManyThrough(Menu::class,restaurant_menu::class,'menu_id','id','id','restaurant_id');
} 

【讨论】:

  • 我做了所有这些,但我必须在菜单表中创建 restaurant_id 字段,我认为这对我没有帮助,你知道,在这种情况下,我有我在其中保存菜单的 menus 表,以及用于数据透视表的 restaurant_menu 以保存每个餐厅的菜单和价格,我很困惑,不知道是什么去做!
  • 如果你想按照你说的那样做,那么你需要在你的模型中使用“hasManyThrough”关系。当我编辑我的答案时。您将在最后一个函数中找到新建议
  • 感谢您的回答,我使用了您的代码并对其进行了一些更改,最终得到了结果!我还有一个问题,如何将 $request 数据存储在 Restaurant_Menu 表中?我有一个餐厅老板的面板,他们将从列表中创建自己的菜单并设置价格,所有这些信息都必须存储在 *Restaurant_Menu 表中。
  • 这完全取决于你。你如何维护你的字体末端设计。您可以轻松地使用下拉选择器,让一个用户选择 restaurant_id 和 menu_id 一个文本字段来设置价格。其他方式您可以选择您的餐厅,然后只需 pic 菜单 ID 并设置价格。但是请记住一件事,如果您使用第二个想法,那么您需要在隐藏文件中传递餐厅 ID。希望你理解
  • 哦,你是对的。我觉得第一个比第二个好。
【解决方案2】:

您定义的关系在构建器实例的 query 范围内不可用,就像您尝试调用它们的方式一样。它们在您的模型上下文中可用。在查询中包含您的关系的方式有所不同 - 您应该检查 official documentation on the matter first

在您的情况下,如果您想选择属于特定餐厅的所有菜单,您必须采取以下方式:

  1. 您可以先获取特定餐厅,然后通过关系获取其菜单:

    $restaurant = Restaurant::find(2);
    $menus = $restaurant->menus;
    
  2. 您可以通过Menu模型查询菜单:

    $menus = Menu::whereHas('restaurants', function ($query) {
        $query->where('id', 2);
    })-get();
    

你的关系也设置错了。根据您提供的表结构,您的菜单和餐厅处于 多对多 关系。因此Menu类中的restaurants()关系方法需要返回BelongsToMany实例。因此,当您使用它时,我强烈建议您阅读 relationships 文档并观看示例,直到您了解 Laravel 中不同关系如何工作的概念。

【讨论】:

  • 你知道,在这种情况下,我有 menus 表,我将菜单保存在其中,restaurant_menu 用于数据透视表以保留每个餐厅菜单和价格,我很困惑,不知道该怎么办!
【解决方案3】:

其实

您以正确的方式定义了关系。我认为,你有一个关于在雄辩的查询中获得这些关系的问题。如果要获取特定餐厅的菜单关系;你必须实现类似的东西。

$restaurant = Restaurants::find(2);
$restaurant->menus(); // this will return an array of related menus.

您应该阅读Laravel Offical documentation。每个关系定义都有检索关系标题。

【讨论】:

  • 我用 echo 和 return 编写了这段代码,得到了这个错误:Object of class Illuminate\Database\Eloquent\Builder could not be converted to string,但是没有 return 和 echo,我没有收到错误,但它什么也没显示。
  • @MahdiAlikhani 这只是一个非常简单的通用 PHP 错误,与 Laravel 无关。正如错误所说,您不能将对象转换为字符串,如果您只想查看对象的内容,那么 var_dump() 就是您所需要的,甚至是更好的 laravels dd() 函数,因此您也可以进行格式化跨度>
  • 正如@twigg 提到的,这是一个通用的 PHP 错误。您必须在其上运行 for 循环。或者你可以通过 Laravel 的 dd 函数得到一个转储。 dd($restaurant->menus());
【解决方案4】:

你们的关系有问题。餐厅模型和菜单模型之间存在一对多的关系。但是,您的表结构表明,它们具有多对多模型。

如果您认为您的模型是正确的,那么请按以下方式更改菜单表,

菜单

-id
-name
-restaurant_id //new field

另外,删除“restaurant_menu”表。

如果您认为您的数据库是正确的,请尝试相应地更改模型。

【讨论】:

  • 你知道,在这种情况下,我有 menus 表,我在其中保存菜单,以及用于数据透视表的 restaurant_menu 以保存每个餐厅的菜单和价格,我很困惑,不要不知道怎么办!
  • 一家餐厅可能有多个菜单。但反过来是真的吗?一份菜单可以适用于多家餐厅吗?如果是,那么您需要一个数据透视表。否则,您应该只在菜单表中使用“restaurant_id”。
猜你喜欢
  • 1970-01-01
  • 2019-06-12
  • 2014-10-21
  • 2015-06-18
  • 2016-03-25
  • 1970-01-01
  • 2016-08-04
  • 1970-01-01
  • 2019-09-08
相关资源
最近更新 更多