[Laravel] Eloquent ORM 1-1/ 1-*/ *-*( Many to Many)

前言

这篇稍微介绍 ORM 操作资料库关联的用法。「1对1」和「1对多」作法相同,须在自己的 tabel 加 Foreign Key,「多对多」需要建立一个关联表(pivot table)。 感谢 Charleen 的文章-Eloquent: Many to Many (前言:创建多对多资料表,踩坑大全)
举餐厅的例子:

一对一 -- 每间餐厅对应一张菜单。一对多 -- 每张菜单有多道菜。多对多 -- 每个人都可以开多个餐厅,每个餐厅可能有多个拥有者。

「1对1」「1对多」

在 menu table 的 Migration 中设定 foreign key 栏位
public function up()    {        Schema::create('menus', function (Blueprint $table) {            $table->unsignedBigInteger('restaurant_id');        }    }

2-1. 在 menu 自己的 Model 中加入 restaurant 函式,用 belongsTo 取出关联的资料

public function restaurant(){    return $this->belongsTo('App\Restaurant');}

2-2. 或是在 restaurant 的 Model 中加入 menu 函式,用 hasOne 或是 hasMany 取出关联的资料

public function menu()    {        return $this->hasOne('App\Menu');    }}
在 Restaurant 的 Controller 中,呼叫函式
Restaurant::with('users')->first()->menu;

{
"id": 1,
"img": "http://localhost:8000/storage/JQmggLcgfEqweLSMzqoqm4x8WV4DIaU5RitsYgjX.jpeg",
"restaurant_id": 1
}

Restaurant::with('menu')->first();

{
"id": 1,
"name": "veg_sasa",
"menu": {
"id": 1,
"img": "http://localhost:8000/storage/JQmggLcgfEqweLSMzqoqm4x8WV4DIaU5RitsYgjX.jpeg",
"restaurant_id": 1
}
}

「多对多」

建立 pivot 表,由两个 Model 的 首字字母顺序建立,且表名称需为单数。
php artisan make:migration create_restaurant_user_table
建立 Model: php artisan make:model RestaurantUser

若是直接用 php artisan make:model UserRestaurant -mc,会自动产生有複数的 table(user_restaurants),这样会有错
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'testorm.restaurant_user' doesn't exist

必须要在关联 Model 中定义使用的 pivot 表名称protected $table = 'restaurant_user'; 若model中没有特地写这行, model会没办法对应到资料库的 table, 因为他会去找预设的 restaurant_users 来作存取在 User 或 Restaurant 的 Model 加上函式对应
public function users()    {        return $this->belongsToMany('App\User');    }
可以在 Model 中将 pivot 栏位隐藏(非必要)
protected $hidden = [        'password', 'remember_token','created_at', 'updated_at','pivot'    ];
捞关联资料 User::with('restaurants')->latest('id')->first();
{    "id": 2,    "name": "erin",    "restaurants": [        {            "id": 1,            "name": "veg_sasa"        },        {            "id": 2,            "name": "veg_elephant"        }    ]}

反向捞关联资料 Restaurant::with('users')->latest('id')->first();

{    "id": 2,    "name": "veg_elephant",    "users": [        {            "id": 2,            "name": "erin"        },        {            "id": 1,            "name": "sarah"        }    ]}

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章