Today I'm going to teach you how to use sync method in laravel and make your developing life easy!


In this tutorial I'm going to tell you 0 to hero about sync method and not just to tell you how to create it but also how to edit and delete it (full CRUD) hope you like it.


  1. We will need table as our options to choose such as tags statuses etc.
  2. We need content table such as posts products etc.
  3. We need third table to combine these two tables id's.


Let's begin

1- Create Tag table

php artisan make:model Tag -m

Note: -m will create migration for you along with model Database(folder)->Migrations (you'll find your product migration file)


2- Create your second table, we will call it Product

php artisan make:model Product -m


3- Make your third table post_tag (note: we don't need any controller or model for this table)

php artisan make:migration create_post_tag_table


4- Create your tags table schema

public function up()
  Schema::create('tags', function (Blueprint $table) {


5- Create your Products table schema

Schema::create('products', function (Blueprint $table) {


6- Create post_tag table schema

public function up()
  Schema::create('post_tag', function (Blueprint $table) {


7- Model relations


7.1 - Add this to your Product model

public function tags(){
     return $this->belongsToMany(Tag::class);

7.2- Add this to your Tag model

public function products(){
     return $this->belongsToMany(Product::class);


8- Create your tables

php artisan migrate

Now you are good to go.


Step Two

1- Create CRUD for your Tags

  • Do it by yourself please! it's simple create,read,update,delete (TagController.php)d

2- Open ProductController and follow steps below


2.1- Use tag (top of your controller)


namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Notifications\Notifiable;
use App\Product;
use Carbon\Carbon;
use App\Tag;

class ProductController extends Controller
// rest of the code...


2.2- Add tags to create method

public function create()
      $tags = Tag::all();
      return view('products.create', compact('tags'));


2.3- Store method

public function store(Request $request)
      //Validating title and body field
      $this->validate($request, array(
          'body' =>'required|min:4|max:100000',
          'slug' =>'required|max:225|unique:posts',
          'image' =>'sometimes|image',

      $product= new Product;

      $product->title = $request->input('title');
      $product->body = $request->input('body');
      $product->slug = $request->input('slug');

      if ($request->hasFile('image')) {
        $image = $request->file('image');
        $filename = 'product' . '-' . time() . '.' . $image->getClientOriginalExtension();
        $location = public_path('images/');
        $request->file('image')->move($location, $filename);

        $product->image = $filename;

      $product->tags()->sync($request->tags, false);

  //Display a successful message upon save
      return redirect()->route('products.index')
          ->with('flash_message', 'Product,
           '. $product->title.' created');

Note: As you probably notice we didn't validate tags in our method instead we sync them after save() . Second part you have to notice is I added false after $request->tags and it's important to be false (don't use true or leave it blank!)


3.3- Normally tutorials you can find it web will ends it this part! but I have plan to teach you completely so let's edit our tags as well cool

public function edit($id)
      $product = Product::findOrFail($id);
      $tags = Tag::all();
      $tags2 = array();
      foreach($tags as $tag) {
        $tags2[$tag->id] = $tag->name;
      return view('posts.edit', compact('product', 'tags2'));


First: as you see I looped our tags in order to get only tags that has been used in specific product which we are going to edit (taken by id).

Second: reason I did that is because I'm using form helper and it's more easy to use in blade rather than using basic html form and foreach it there. (I show you later how to)

Third: pay attention i compacted tags2 and not tags which is our loop.

3.4 - Update method

public function update(Request $request, $id)
       // rest of codes...


      return redirect()->route('products.index',
          'Product, '. $product->title.' updated');


Note: here we are not going to use false anymore.


3.5 - Delete method

public function destroy($id)
      $product = Product::findOrFail($id);

      return redirect()->route('products.index')
           'Product successfully deleted');

and we simply just detach tags from our deleted product which will delete relation in our post_tag table.


Step Three

I already made this tutorial the most complete once on the web but let's take one step forther and teach you how to use it in blade (create and edit)

1- First thing first, go to this website and download css and js files.

* we will use it in order to select multiple tags for each product.


2- Load css and js files in your blade

<link rel="stylesheet" href="{{asset('css/select2.min.css')}}">
<script src="{{asset('js/select2.min.js')}}"></script>

// use basic javascript
<script type="text/javascript">


3- Add class to your select form

{{ Form::label('tags', 'Tags:') }}
<select class="tagsselector form-control" name="tags[]" multiple="multiple">
   @foreach($tags as $tag)
     <option value="{{ $tag->id }}">{{ $tag->name }}</option>

Note: We will get our tags in array name="tags[]" also we added multiple="multiple" in our form.


4- Test it out smile you made your first product with multiple tags. congrats.




5- Edit form

remember we got our tags in loop and called tags2 ? here is the reason:

{{ Form::label('tags', 'Tags:', array('class' => 'mt-20')) }}
{{Form::select('tags[]', $tags2, null, ['class' => 'form-control tagsselector', 'multiple' => 'multiple'])}}


Now try to edit your product and see the result. also you can check post_tag table to see changes on create and edit products.


Please share your opinion about this tutorial in comments.

Share this article: