Laravel-Backpack / CRUD

Build custom admin panels. Fast!
https://backpackforlaravel.com
MIT License
3.08k stars 885 forks source link

select2_from_ajax setting my value as null after the correct value has been saved #3381

Closed gthu96 closed 3 years ago

gthu96 commented 3 years ago

Im having a weird problem. Im using laravel backpack for an admin panel. There i use select2_from_ajax to list a values according to another field in create operation. It is showing up correctly as expected & i can select one too. But after selection when i click save & back it gives me an error

Screenshot_2020-12-03 🧨 SQLSTATE 23000  Integrity constraint violation 1048 Column 'link_to' cannot be null (SQL update `g

That means my column doesn't allow to update to null right. So when i go back & check the column it has saved the correct value. But when default value of my column was null this error will not showup & db value would be changed to null.

This is my select2_from_ajax part.

    $this->crud->addField([  // Select
        'label' => "Link Type",
        'type' => 'select_from_array',
        'name' => 'link_type', // the db column for the foreign key
        'options'     => [1 => 'Product',0 => 'Collection'],
        'allows_null' => false,
    ]);

    $this->crud->addField([  // Select
        'label' => "Link To", // Table column heading
        'type' => "select2_from_ajax",
        'name' => "link_to",
        'entity' => 'link',
        'attribute'   => "name",
        'data_source' => url('admin/itemtype'),
        'placeholder' => "Select a item",
        'minimum_input_length' => 0,
        'include_all_form_fields' => true,
        'dependencies' => ['link_type'],
    ]);

My admin/itemtype function:

$search_term = $request->input('q');
    $form = collect($request->input('form'))->pluck('value', 'name');

    if ($search_term) {
        if ($form['link_type'] == 0) {
            $items = Collection::where('name', 'LIKE', '%' . $search_term . '%')->paginate(10);
        } else {
            $items = Product::where('title', 'LIKE', '%' . $search_term . '%')->paginate(10);
        }
    } else {
        if ($form['link_type'] == 0) {
            $items = Collection::paginate(10);
        } else {
            $items = Product::paginate(10);
        }
    }

    return $items;

@pxpm According to link_type my link_to select values changes. So if the lint_type is chosen as collection link_to will list all the collections in db & if its product it will list out all the products from the database.

So at the create operation everything is listed as expected. I can select link_type & link_to will come according to that. When i select product as link_type & select a product to link_to & click save & back, it will show that first sql error image.

After that when i check the database it has saved the correct value eventhough this error was shown.

So what i make of this is that it is trying to update already saved correct value with null.

model relation link:

public function link()
    {
        if ($this->link_type == 0) {
            return $this->belongsTo('App\Models\Collection', 'link_to');
        } else {
            return $this->belongsTo('App\Models\Product', 'link_to');
        }
    }

Backpack, Laravel, PHP, DB version

When I run php artisan backpack:version the output is:

PHP 7.4.9 (cli) (built: Aug 7 2020 14:29:36) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies with Zend OPcache v7.4.9, Copyright (c), by Zend Technologies

LARAVEL VERSION:

v7.28.3@b0942c391975972b1a54b2dc983e33a239f169a9

BACKPACK VERSION:

4.1.25@23fb1ed5153d5465d49d2fe1ca265a5985c78877

welcome[bot] commented 3 years ago

Hello there! Thanks for opening your first issue on this repo!

Just a heads-up: Here at Backpack we use Github Issues only for tracking bugs. Talk about new features is also acceptable. This helps a lot in keeping our focus on improving Backpack. If you issue is not a bug/feature, please help us out by closing the issue yourself and posting in the appropriate medium (see below). If you're not sure where it fits, it's ok, a community member will probably reply to help you with that.

Backpack communication channels:

Please keep in mind Backpack offers no official / paid support. Whatever help you receive here, on Gitter, Slack or Stackoverflow is thanks to our awesome awesome community members, who give up some of their time to help their peers. If you want to join our community, just start pitching in. We take pride in being a welcoming bunch.

Thank you!

-- Justin Case The Backpack Robot

pxpm commented 3 years ago

Hello @gthu96 thank you for submitting this issue.

I am not sure I fully understand what you mean, could you please rephrase it ? Like in simple steps:

Something along those lines so I can try to replicate what you are trying to achieve and it's failing. It could be or not a bug, but I do not fully understood your question, so sorry for that.

Also it would help if you can provide you relation link that you have defined in the model.

Thanks in advance, Pedro

gthu96 commented 3 years ago

@pxpm Hi thanks for the reply. I have updated the question

ashwin-nath-m commented 3 years ago

Having same issue. I am not getting the sql error but its setting the value to null.

pxpm commented 3 years ago

Thank you @gthu96 for the clarification.

At first sight I think this might be related with #3250

I am going to give this a try and will come back to you guys with my findings.

@gthu96 @ashwin-nath-m your column in database is nullable or non-nullable ?

gthu96 commented 3 years ago

@pxpm Thanks for the reply. When i set link_to as non nullable it will show me that sql error, but when i check db it has saved the correct value for link_to. When i set it nullable, this error won't show up but the value which get saved in link_to will be null.

pxpm commented 3 years ago

Hum, I am not sure your relations are well defined.

It seems you need a polymorphic relation. When you save let's say link_to => 4, how do you know it's related to a Product or a Collection ? By having the link_type ? That's exactly a polymorphic relation. https://laravel.com/docs/8.x/eloquent-relationships

I don't think you can define a belongsTo like that.

gthu96 commented 3 years ago

Could you share/link to an example/documentation using select2_from_ajax & polymorphic relation ?.

nihadatakishiyev commented 3 years ago

I am also experiencing a similar issue. @gthu96 did you manage to solve your problem? If yes, could you please share your solution?

promatik commented 3 years ago

Hi everyone, to make sure select2_from_ajax, select2_from_ajax_multiple was working with polymorphic relations I took as example the UserCrudController on demo.

Both Roles and Permissions are polymorphic relationships, I was able to create fields for those; image

@nihadatakishiyev and @gthu96, I'll leave here the fields code for you and any one who may need this in future;

$this->crud->addField([
    'label' => trans('backpack::permissionmanager.roles'),
    'type' => 'select2_from_ajax_multiple',
    'name' => 'roles',
    'entity' => 'roles',
    'attribute' => 'name',
    'data_source' => url('api/roles'),
    'pivot' => true,
    'model' => "Backpack\PermissionManager\app\Models\Role",
    'placeholder' => 'Select roles',
    'minimum_input_length' => 2,
]);

To create the morphToMany relation on model the code for Role is something like this;

public function roles()
{
    return $this->morphToMany(
        Role::class, // related model class
        'model', // name
        'roles', // table name
        'model_id', // foreign pivot key
        'role_id' // related pivot key
    );
}

More info on morphToMany on Laravel Docs.

This is for Roles, it works exactly the same for Permissions. I'll close the issue for now, please open if you find any issues 👍