laraveleloquenthas-and-belongs-to-many

get many to many values and which of them are selected in laravel


Contacts:
id
name

Tags:
id
name

ContactTags:
contact_id
tag_id

In Contacts model:

public function tags()
{
    return $this->belongsToMany(Tags::class, "contacts_tags", "contact_id", "tag_id");
}

So if I do

$contact = Contacts::findOrFail($id);
dd($contact->tags);

I successfully get the tags associated with the contact. But how can I get all tags and a flag indicating which one of those is associated?

I'm trying to prevent fetching all tags, loop them and with each iteration loop all contact_tags and check if tag_id matches. I want to display a list of checkboxes with all tags and check the ones that are in the relation.


Solution

  • This code can help you, but I'm using the SELECT multiple component. You can easily adapt it to use the CHECKBOX component.

    Contacts model:

    public function tags()
    {
        return $this->belongsToMany(Tags::class, "contacts_tags", "contact_id", "tag_id");
    }
    

    ContactController.php

    public function edit(Contact $contact)
    {
        $tags = Tag::all();
        return view('contacts.edit',compact('contact', 'tags'));        
    }
    

    edit.blade.php

    <div class="row">
            <div class="col">
                <div class="form-group">
                    <strong>Tags:</strong>
                    <select name="tags_id[]" multiple>
                        @foreach ($tags as $tag)
                            @if( $contact->tags->contains($tag) )
                                <option value="{{ $tag->id }}" selected>{{ $tag->name }}</option>
                            @else
                                <option value="{{ $tag->id }}">{{ $tag->name }}</option>
                            @endif
                        @endforeach
                    </select>
                </div>
            </div>
        </div>
    

    Update in ContactController.php

    public function update(Request $request, Post $contact)
    {   
        $validatedData = $request->validate([
                'tags_id' => ['array'],
            ]);
    
        $contact->update($request->all());
        $contact->tags()->sync($validatedData['tags_id']); 
    
        return redirect()->route('contact.index')->with('success', 'Contact successfully updated!');
    }
    

    The validation is just an example. The $validatedData has no use here, but it can be used to update the contact if you validate the other fields.