Laravel study notes (21) model relationships (one to one, one to many, many to many)

  1. One to One

To form the corresponding table

// 自动表名为identity_cards,手动migration名为create_identity_cards_table
php artisan make:migration create_identity_cards_table

// 手动表名为identity_cards,手动migration名为create_identity_cards_table
php artisan make:migration --create=identity_cards create_identity_cards_table

Generation model factories and model

php artisan make:model IdentityCard

php artisan make:factory IdentityCardFactory --model=IdentityCard

Configuring model relationships in the model

// App\User
public function identity_card(){
    return $this->hasOne('App\IdentityCard');
}

// App\IdentityCard
public function user(){
    return $this->belongsTo('App\User');
}

App \ IdentityCard because it is new, do not forget to add white list:protected $guarded = [];

Whether the test model relationship success

increase

$card = new App\IdentityCard(['city' => '上海']);

$user = App\User::create([
    'name' => request('name'),
    'email' => request('email'),
    'password' => request('password'),
]);

$user->identity_card()->save($card);		// 因为命名正确,会自动填充user_id 

// 或者
$user = factory(\App\User::class)->create();

$user->identity_card()->create(factory(\App\IdentityCard::class)->make()->toArray());		// 因为命名正确,会自动填充user_id

delete

// 删除某个用户的身份证
$user = \App\User::find(1);
$user->identity_card()->delete();

// 删除某张身份证的主人
\App\IdentityCard::find(3)->user()->delete();

change

$card = \App\IdentityCard::find(6);
$card->user()->dissociate();		// 删除关联,设置外键为null
$card->save();

$user = App\User::find(2);
$card = App\IdentityCard::find(6);
$card->user()->associate($user);		// 追加关联,设置外键为null
$card->save();

check

// 1. 普通方式(建议使用下面一种)
$cards = App\IdentityCard::find([1, 2]);
foreach ($cards as $card) {
    echo $card->user->name;
}
// 先找出两张ID卡信息,再分别通过ID卡的USER_ID去找用户信息,执行 1+n 次SQL
// select * from identity_cards where id in (1, 2)
// 找到user_id = 3和user_id = 4
// select * from users where id = 3
// select * from users where id = 4

// 2. 延迟加载
$cards = App\IdentityCard::with('user')->find([1, 2]);
foreach ($cards as $card) {
    echo $card->user->name;
}
// 先找出两张ID卡信息,再将USER_ID变成一个集合,通过这个集合去找用户信息,执行 1+1 次SQL
// select * from identity_cards where id in (1, 2)
// 找到user_id = 3和user_id = 4
// select * from users where id in (3, 4)

Special wording

# users: id, name
# identity_cards: id, city, user_name

// App\User,外键是user_name,外键中的值为users.name
public function identity_card(){
    return $this->hasOne('App\IdentityCard', 'user_name', 'name');
}
  1. Many

The establishment of table structure

# articles: id, title, content
# comments: id, content, article_id

Configuring model relationships in the model

// App\Article
public function comments(){
    return $this->hasMany('App\Comment');
}

// App\Comment
public function article(){
    return $this->belongsTo('App\Article');
}

increase

$article = App\Article::find(1);
$article->comments()->create(['content' => '12346']);

delete

$article = App\Article::find(1);
$article->comments()->where('id', '2')->delete();

change

$comment = App\Comment::find(11);
$article = App\Article::find(1);
$comment->article()->associate($article);
$comment->save();

$comment = App\Comment::find(1);
$comment->article()->update(['title' => '广州在哪儿']);

check

$comments = App\Article::find(1)->comments;

$comments = App\Article::find(1)->comments()->where('content', 'like', '%教学%')->get();

$article = App\Comment::find(1)->article;

// 延迟加载
App\Ariticle::with('comments')->find(2)
// select * from articles where id = 2
// select * from comments where id in (1, 2, 3, .....)

Special wording

# articles: id, title, content
# comments: id, content, article_title

// App\Article,外键是article_title,外键中的值为articles.title
public function comments(){
    return $this->hasMany('App\Comment', 'article_title', 'title');
}
  1. Many to many

The establishment of table structure

# users: id, name
# roles: id, title
# role_user: id, role_id, user_id

Model configuration

// App\Role
public function users(){
	// withTimestamps()自动维护中间表时间字段
    return $this->belongsToMany('App\User')->withTimestamps();
}

// App\User
public function roles(){
	// withTimestamps()自动维护中间表时间字段
    return $this->belongsToMany('App\Role')->withTimestamps();
}

increase

$user = App\User::find(1);
$user->roles()->attach($roleId); 
// $roleId = 1;
// $roleId = [1, 2];
// $roleId = Role::find(1);

$user->roles()->attach($roleId, ['expires' => $expires]);

$user->roles()->attach([
    1 => ['expires' => $expires],
    2 => ['expires' => $expires],
]);

delete

$user->roles()->detach($roleId);

$user->roles()->detach();

change

Leaving only role_id in sync

$user->roles()->sync([1, 2, 3]);

Here Insert Picture Description

// update `role_user` set `expires` = 1, `updated_at` = 2020-02-14 12:52:13 where `user_id` = 1 and `role_id` in (3))
$user->roles()->sync([1 => ['expires' => true], 2, 3]);

// 在只有roles_id=3和roles_id=4的情况下,追加roles_id=1和roles_id=2
$user->roles()->syncWithoutDetaching([1, 2, 3]);

Here Insert Picture Description

// toggle切换数据,有就attach,没有就detach
$user->roles()->toggle([1, 2, 3]);

// 更新中间表记录
$user = App\User::find(1);
// $user->roles()->updateExistingPivot($roleId, $attributes);
$user->roles()->updateExistingPivot(2, ['status'=>false]);
// 等效于update `role_user` set `status` = 0, `updated_at` = 2020-02-14 13:03:41 where `user_id` = 1 and `role_id` in (2))'

check

// 查找一个用户的所有角色
$user = User::find(1);
$user->roles;

$user = User::find(1);
$user->roles()->wherePivot('role_id', $id)->first();

// 延迟加载,查出角色是1和2的所有用户
Role::with('users')->find([1, 2]);

Custom Model

    public function users() {
    	// 自定义中间表为role_user,外键role_id,相关键user_id
        return $this->belongsToMany(User::class, 'role_user', 'role_id', 'user_id')
            ->withTimestamps();
    }

Remove Field intermediate

$user = App\User::find(1);

foreach ($user->roles as $role) {
	// 获得中间表的role_id
    echo $role->pivot->role_id;
}

Rename the pivot

return $this->belongsToMany('App\Role')->as('subscription');

// 此处pivot变为subscription 
$role->subscription->role_id;

Add created_at in the pivot, updated_at

return $this->belongsToMany('App\Role')->withTimestamps();

Add additional fields in the pivot

return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');

Model relationships and set the filter

return $this->belongsToMany('App\Role')->wherePivot('approved', 1);

return $this->belongsToMany('App\Role')->wherePivotIn('priority', [1, 2]);
Published 40 original articles · won praise 0 · Views 770

Guess you like

Origin blog.csdn.net/qj4865/article/details/104315216