craftable icon indicating copy to clipboard operation
craftable copied to clipboard

Many to many relationship

Open fernando1419 opened this issue 4 years ago • 4 comments

Hi, excellent work!!. I have a question, how can I create a many to many relationship in Craftable?, for instance: articles, tags and article_tag?. I couldn't find any doc about this issue. Do you have any ideas?. Thanks in advance.

fernando1419 avatar Mar 10 '20 01:03 fernando1419

@fernando1419 I was able to use spatie's laravel tags. https://github.com/spatie/laravel-tags If you still need to do this, I can show you how I implemented it.

jigzstar avatar Sep 23 '21 13:09 jigzstar

Sure, that would be great, thank you!.

El jue, 23 sept 2021 a las 10:44, Joakim George @.***>) escribió:

@fernando1419 https://github.com/fernando1419 I was able to use spatie's laravel tags. https://github.com/spatie/laravel-tags If you still need to do this, I can show you how I implemented it.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/BRACKETS-by-TRIAD/craftable/issues/205#issuecomment-925829937, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAGFN6FA7DG7ZXVHP7RURQLUDMVM5ANCNFSM4LEU37KQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

fernando1419 avatar Sep 23 '21 18:09 fernando1419

ok, here goes.

  1. Install laravel tags

Model

use Spatie\Tags\HasTags;

Controller

    public function create()
    {
        $this->authorize('admin.member-claim.create');

        return view('admin.member-claim.create', [
            ...
            'availableTags' => Tag::getWithType('claimType')  // if using types
            ]
        );
    }

  public function store()
 {
      $tags = Arr::pluck($sanitized['type'],'name'); // get from request variable
      $memberClaim = MemberClaim::create($sanitized); // create ur model
      $memberClaim->syncTagsWithType($tags, 'claimType'); // save the selected tags

 }

Blade View


// create view
        <member-claim-form
            :action="'{{ url('admin/member-claims') }}'"
           ...
            :available-tags="{{ $availableTags->map(function($availableTag) { return ['id' => $availableTag->id, 'name' =>  $availableTag->name]; })->toJson() }}"

// form element

<div class="form-group row align-items-center"
     :class="{'has-danger': errors.has('claim_type'), 'has-success': this.fields.claim_type && this.fields.claim_type.valid }">
    <label for="claim_type"
           class="col-form-label text-md-right" :class="isFormLocalized ? 'col-md-4' : 'col-md-2'" >{{ trans('admin.member-claim.columns.claim_type') }}</label>
    <div :class="isFormLocalized ? 'col-md-4' : 'col-md-9 col-xl-8'">

        <multiselect
                v-model="form.type"
                :options="availableTags"
                :multiple="true"
                track-by="id"
                label="name"
                :taggable="true"
                @tag="addTag"
                tag-placeholder="Add this as a new type of claim"
                tag-placeholder="{{ __('Select Claim Type') }}"
                placeholder="{{ __('Claim Type') }}">
        </multiselect>

        <div v-if="errors.has('claim_type')" class="form-control-feedback form-text" v-cloak>@{{
            errors.first('claim_type') }}
        </div>
    </div>
</div>

Vuejs View

Vue.component('member-claim-form', {
    mixins: [AppForm],
    props: [
      ...
        'availableTags'
    ],
    data: function() {
        return {
            form: {
               ...
                type: [],
            }
    },
       methods: {
        addTag (newTag) {
            const tag = {
              name: newTag,
            }
            this.form.type.push(tag)
      
        },
        ...
   }

Index

<td>@{{ item.tags_translated[0].name_translated }}</td> // Can loop if you need to get a list

You can also generate a Tags model, for managing tags separately

For saving I used:

        // creating
        $tag = \Spatie\Tags\Tag::findOrCreate($sanitized['name'], 'claimType'); 

    public function update(UpdateTag $request, \Spatie\Tags\Tag $tag)
    {
        // Sanitize input
        $sanitized = $request->getSanitized();

        // Update changed values Tag
        $tag->name = $sanitized['name'];
     
        $tag->order_column = $sanitized['order_column'];
        
        $tag->save();
    }

I hope this helps !

jigzstar avatar Sep 25 '21 23:09 jigzstar

Thank you very much for your help!. I'll have a look at it. Regards.

El sáb, 25 sept 2021 a las 20:32, Joakim George @.***>) escribió:

ok, here goes.

  1. Install laravel tags

Model

use Spatie\Tags\HasTags;

Controller

public function create()
{
    $this->authorize('admin.member-claim.create');

    return view('admin.member-claim.create', [
        ...
        'availableTags' => Tag::getWithType('claimType')  // if using types
        ]
    );
}

public function store() { $tags = Arr::pluck($sanitized['type'],'name'); // get from request variable $memberClaim = MemberClaim::create($sanitized); // create ur model $memberClaim->syncTagsWithType($tags, 'claimType'); // save the selected tags

}

Blade View

// create view <member-claim-form :action="'{{ url('admin/member-claims') }}'" ... :available-tags="{{ $availableTags->map(function($availableTag) { return ['id' => $availableTag->id, 'name' => $availableTag->name]; })->toJson() }}" // form element

    <multiselect
            v-model="form.type"
            :options="availableTags"
            :multiple="true"
            track-by="id"
            label="name"
            :taggable="true"
            @tag="addTag"
            tag-placeholder="Add this as a new type of claim"
            tag-placeholder="{{ __('Select Claim Type') }}"
            placeholder="{{ __('Claim Type') }}">
    </multiselect>

    <div v-if="errors.has('claim_type')" class="form-control-feedback form-text" v-cloak>@{{
        errors.first('claim_type') }}
    </div>
</div>

Vuejs View

Vue.component('member-claim-form', { mixins: [AppForm], props: [ ... 'availableTags' ], data: function() { return { form: { ... type: [], } }, methods: { addTag (newTag) { const tag = { name: newTag, } this.form.type.push(tag)

    },
    ...

}

Index

@{{ item.tags_translated[0].name_translated }} // Can loop if you need to get a list

You can also generate a Tags model, for managing tags separately

For saving I used:

    // creating
    $tag = \Spatie\Tags\Tag::findOrCreate($sanitized['name'], 'claimType');

public function update(UpdateTag $request, \Spatie\Tags\Tag $tag)
{
    // Sanitize input
    $sanitized = $request->getSanitized();

    // Update changed values Tag
    $tag->name = $sanitized['name'];

    $tag->order_column = $sanitized['order_column'];

    $tag->save();
}

I hope this helps !

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/BRACKETS-by-TRIAD/craftable/issues/205#issuecomment-927198103, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAGFN6BIDW7S64L22VUINKLUDZLZPANCNFSM4LEU37KQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

fernando1419 avatar Sep 25 '21 23:09 fernando1419