Author: Shiannizhilu public number: Zhixing Research Institute

13.1 Associate Adding

1. For example, there is a function: add related books to a user. Then the method is as follows.

First look at the book table, there is no time field, you need to cancel the automatic write time. Cancel batch assignment for the book table as well:

// Cancel batch assignment
protected $guarded = [];
// Cancel the automatic time field
public $timestamps = false;
Copy the code

Then in the control class write:

// Limit the user first
$user = User::find(19);
// Add a new record to the book associated with the user
// User_id is automatically written to 19, title is customized
$user->book()->save(new Book(['title'= >'Harry Potter']));
Copy the code

Then run, which executes SQL as:

select * from `laravel_users` where `laravel_users`.`id` = 19 limit 1
insert into `laravel_books` (`title`, `user_id`) values ('Harry Potter'.19)
Copy the code

Of course, you can also add batch:

// Limit the user first
$user = User::find(19);
// Add a batch
$user->book()->saveMany([
    new Book(['title'= >'Harry Potter']),
    new Book(['title'= >'Lord of the Rings']]);Copy the code

It executes SQL as follows:

select * from `laravel_users` where `laravel_users`.`id` = 19 limit 1
insert into `laravel_books` (`title`, `user_id`) values ('Harry Potter'.19)
insert into `laravel_books` (`title`, `user_id`) values ('Lord of the Rings'.19)
Copy the code

2, create and createMany only need to insert an array to complete the associated new;

Such as:

// Limit the user first
$user = User::find(19);
// Insert by association
$user->book()->create([
    'title'= >'Harry Potter'
]);
Copy the code

Such as:

// Limit the user first
$user = User::find(19);
// Associate batch inserts
$user->book()->createMany([
    ['title'= >'Harry Potter'],
    ['title'= >'Lord of the Rings']]);Copy the code

The execution result is the same as above.

FindOrNew, firstOrNew, firstOrCreate, and updateOrCreate methods;

FindOrNew: Find a model by its primary key or return new instance of the related model.

FirstOrNew: Get the first related model record matching the attributes or instantiate it.

FirstOrCreate: Get the first related record matching the attributes or create it.

Update: Create or update a related record matching the attributes, and fill it with values.

Such as:

// Limit the user first
$user = User::find(19);

return $user->book()->firstOrNew([
    'title'= >'Harry Potter'
]);
Copy the code

This approach, in which title related data is returned if it can be found, and in which a model (non-database insertion) is generated and returned, is temporary.

Such as:

// Limit the user first
$user = User::find(19);

return $user->book()->firstOrCreate([
    'title'= >'Harry Potter'
]);
Copy the code

In this way, the data associated with title is returned if it can be found, and if not, the data is inserted into the database, and then the inserted data is returned.

13.2 Associated Delete

Use delete() for associated deletes. Such as:

// Delete the book with user_id=19
$user = User::find(19);
$user->book()->delete();
Copy the code

Execute SQL as:

select * from `laravel_users` where `laravel_users`.`id` = 19 limit 1

delete from `laravel_books` where `laravel_books`.`user_id` = 19 and `laravel_books`.`user_id` is not null
Copy the code

13.3 Associated Changes

1. Use the update() method to make associated changes. Such as:

// Associate modify, modify user_id=19 book
$user = User::find(19);
$user->book()->update(['title'= >'Revision books']);
Copy the code

Execute SQL as:

select * from `laravel_users` where `laravel_users`.`id` = 19 limit 1

update `laravel_books` set `title` = 'Revision books' where `laravel_books`.`user_id` = 19 and `laravel_books`.`user_id` is not null
Copy the code

Associate () alter user (id, user_id);

// Change the associated foreign key, that is, if user_id is changed, the user is changed
$user = User::find(20);
$book = Book::find(9);
$book->user()->associate($user);
$book->save();
Copy the code

Execute SQL as:

select * from `laravel_users` where `laravel_users`.`id` = 20 limit 1
select * from `laravel_books` where `laravel_books`.`id` = 9 limit 1
update `laravel_books` set `user_id` = 20 where `id` = 9
Copy the code

In addition, if you want to cancel the ownership of a book, such as setting user_id to NULL, the field can be set to NULL;

$book = Book::find(8);
$book->user()->dissociate();
$book->save();
Copy the code

Execute SQL as:

select * from `laravel_books` where `laravel_books`.`id` = 8 limit 1
update `laravel_books` set `user_id` = ' ' where `id` = 8
Copy the code

3. When searching for the corresponding user of the book, null field will cause the user to have null data; We can solve this problem by adopting the default model of empty objects;

In the Book model, append the withDefault() method to the associated code, as shown below:

//Book.php
public function user()
{
    return $this->belongsTo(User::class, 'user_id'.'id')
        ->withDefault([
            'id'= >0.'username'= >'Visitor user'
        ]);
}
Copy the code

13.4 Adding, deleting, and modifying many-to-many associations

Add, delete and change are the middle table.

1. Many-to-many: For example, add a role to a user, as follows:

// Get the user to whom you want to add permissions
$user = User::find(99);
// Get the id of the permission, such as super administrator
$roleId = 1;
// Set Hui Ye as super administrator
$user->role()->attach($roleId);
Copy the code

Execute SQL as:

select * from `laravel_users` where `laravel_users`.`id` = 99 limit 1
insert into `laravel_role_users` (`role_id`, `user_id`) values (1.99)
Copy the code

If you want to attach the details field to the intermediate table, use the second parameter.

// Get the user to whom you want to add permissions
$user = User::find(99);
// Get the id of the permission, such as super administrator
$roleId = 1;
// Set Hui Ye as super administrator
///$user->role()->attach($roleId);
$user->role()->attach($roleId['details'= >'cascades']); // The second parameter
Copy the code

Execute SQL as:

select * from `laravel_users` where `laravel_users`.`id` = 99 limit 1
insert into `laravel_role_users` (`details`, `role_id`, `user_id`) values ('cascades'.1.99)
Copy the code

Detach () detach() if you want to detach a user from the role.

// User with permission
$user = User::find(99);
// Id of the permission, such as super administrator
$roleId = 1;
// Delete the permission of a role
$user->role()->detach($roleId);
Copy the code

Execute SQL as:

select * from `laravel_users` where `laravel_users`.`id` = 99 limit 1
delete from `laravel_role_users` and `user_id` = 99 and `role_id` in (1)
Copy the code

If the intermediate table ID ($roleId) is not specified, then all permissions for this user are removed.

4, also support batch processing, directly pass parameters with array;

// The ID of the role permission table is passed
$user->role()->attach([1.2.3]); // detail: 1 => ['detail' => 'XXX ']
// Delete the specified user_id
$user->role()->detach([1.2.3]);
Copy the code

Such as:

// User with permission
$user = User::find(99);
// The ID of the role permission table is passed
$user->role()->attach([1= > ['details'= >'11111'].2= > ['details'= >'222222'].3= > ['details'= >'333333']]);
Copy the code

Execute SQL as:

select * from `laravel_users` where `laravel_users`.`id` = 99 limit 1
insert into `laravel_role_users` (`details`, `role_id`, `user_id`) values ('11111'.1.99), ('222222'.2.99), ('333333'.3.99)
Copy the code

Such as:

// User with permission
$user = User::find(99);
// Delete the specified user_id
$user->role()->detach([1.2.3]);
Copy the code

Execute SQL as:

select * from `laravel_users` where `laravel_users`.`id` = 99 limit 1
delete from `laravel_role_users` where `user_id` = 99 and `role_id` in (1.2.3)
Copy the code

5. Using the sync() method, you can add role permissions and judge that they already exist.

// Synchronize the association. It already exists and cannot be added
return $user->role()->sync([1.2.3]); // detail: 1 => ['detail' => 'XXX ']
Copy the code

Such as:

// User with permission
$user = User::find(99);
// Synchronize the association. It already exists and cannot be added
return $user->role()->sync([1.2.3]);
Copy the code

The first SQL execution is as follows:

select * from `laravel_users` where `laravel_users`.`id` = 99 limit 1
select * from `laravel_role_users` where `user_id` = 99
insert into `laravel_role_users` (`role_id`, `user_id`) values (1.99)
insert into `laravel_role_users` (`role_id`, `user_id`) values (2.99)
insert into `laravel_role_users` (`role_id`, `user_id`) values (3.99)
Copy the code

Then execute it again, executing SQL:

select * from `laravel_users` where `laravel_users`.`id` = 99 limit 1
select * from `laravel_role_users` where `user_id` = 99
Copy the code

This is because the judgment already exists, so there’s no need to add it.

Next, modify the code to:

// User with permission
$user = User::find(99);
// Synchronize the association. It already exists and cannot be added
return $user->role()->sync([1.2.4]);// Change the last one to 4
Copy the code

Then execute again, its SQL is:

select * from `laravel_users` where `laravel_users`.`id` = 99 limit 1
select * from `laravel_role_users` where `user_id` = 99
delete from `laravel_role_users` where `user_id` = 99 and `role_id` in (3)
insert into `laravel_role_users` (`role_id`, `user_id`) values (4.99)
Copy the code

Notice here, I’m deleting the 3 that already exists.

6. Use udpateExistingPivot() to update an additional field with the specified roleId;

// Update the additional fields in the middle table
$user->role()->updateExistingPivot($roleId['details'= >'cascades']);
Copy the code

Such as:

// User with permission
$user = User::find(99);
$roleId = 1;
// Update the additional fields in the middle table
$user->role()->updateExistingPivot($roleId['details'= >'Hahaha']);
Copy the code

It executes SQL as follows:

select * from `laravel_users` where `laravel_users`.`id` = 99 limit 1
update `laravel_role_users` set `details` = 'Hahaha' where `user_id` = 99 and `role_id` in (1)
Copy the code

Using update() directly is to update all;

Such as:

// User with permission
$user = User::find(99);
// Update the additional fields in the middle table
$user->role()->update(['details'= >'Hehe hehe']);
Copy the code

It executes SQL as follows:

select * from `laravel_users` where `laravel_users`.`id` = 99 limit 1
update `laravel_roles` inner join `laravel_role_users` on `laravel_roles`.`id` = `laravel_role_users`.`role_id` set `details` = 'Hehe hehe' where `laravel_role_users`.`user_id` = 99
Copy the code

Select * from database where user_id=99 and details = ‘hehehehe’;

In addition: by viewing the source code or IDE code hint method, there are more operations; Read and expand by yourself.

The above.