前言
这篇稍微介绍 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
必须要在关联 Model 中定义使用的 pivot 表名称若是直接用
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
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" } ]}