platform icon indicating copy to clipboard operation
platform copied to clipboard

Matrix field don't delete a row if this is the last row present for the field

Open gioacchinopoletto opened this issue 2 years ago • 0 comments

Describe the bug Matrix field don't delete a row if this is the last row present for the field, because on MySQL return this error: Check constraint 'people_chk_2' is violated. All changes were reverted (DDL statements can't be reverted).

It seems that on deleting the last row the field will be saved as NULL and not as empty JSON and constraint violation error break last row deletion.

To Reproduce Steps to reproduce the behavior:

  1. Try to add one or more rows to a matrix field
  2. Try to delete the last row on the field --> field empty as result

Expected behavior As expected the matrix field should be empty deleting last row present.

Screenshots N/A

Desktop (please complete the following information):

  • OS: OSX 12.5 Monterey
  • Browser: Safari 15.6 (17613.3.9.1.5), Google Chrome 104.0.5112.79

Smartphone (please complete the following information): Not tested yet

Server (please complete the following information):

  • Platfrom Version: 13.1.0
  • Laravel Version: 9.23.0
  • PHP Version: 8.1.9
  • Database: MySQL
  • Database Version: 8.0.27

Additional context Table field - emails in my case - is casted as array on model, and created as Jsonb on migration: $table->jsonb('emails')->comment("Email addresses")->nullable();

When I have runned the migration MySQL create: emails longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin COMMENT Email addresses CONSTRAINT people_chk_2 CHECK (json_valid('emails'))

gioacchinopoletto avatar Aug 09 '22 09:08 gioacchinopoletto

This seems more like a problem on your side than an Orchid issue. The matrix field returns an array, and it is up to you what you do with that in your function.

astersnake avatar Aug 11 '22 17:08 astersnake

This seems more like a problem on your side than an Orchid issue. The matrix field returns an array, and it is up to you what you do with that in your function.

I think isn't a problem on my side because I don't have find something on documentation about Matrix field that not save an empty array if you delete the entire field content. Probably I don't know if I have used the correct field type definition on my migration (jsonb) because on deleting last value pair or array Orchid set field to NULL and not as an empty array.

gioacchinopoletto avatar Aug 12 '22 07:08 gioacchinopoletto

Can you share a minimal reproducible example or screen where you obtain this behavior?

astersnake avatar Aug 14 '22 22:08 astersnake

I will close this as it is inactive and probably not an Orchid issue.

astersnake avatar Aug 17 '22 16:08 astersnake

I will close this as it is inactive and probably not an Orchid issue.

Why? Some issues still open for months... But, anyway I think I have written all elements to reproduce this behavior. Screens are unuseful in this case.

gioacchinopoletto avatar Aug 20 '22 11:08 gioacchinopoletto

We're working on improving the issues on this repository.

Orchid doesn't save/update anything on your database when you use an input field. It is up to you to save it (using a function) and treat it before saving. I asked for more code on your side because this doesn't seem like an Orchid issue.

astersnake avatar Aug 20 '22 14:08 astersnake

We're working on improving the issues on this repository.

Orchid doesn't save/update anything on your database when you use an input field. It is up to you to save it (using a function) and treat it before saving. I asked for more code on your side because this doesn't seem like an Orchid issue.

I know this, in fact I save, edit and delete the matrix field (emails in my table) without problem with standard save function:

public function save(People $people, Request $request)
  {
        $this->exists = $people->exists;
        
        $request->validate([
           (omissis) 

            'people.emails' => [
                'nullable',
            ],

           (omissis) 
        ]);
        
        $people
            ->fill($request->get('people'))
            ->save();

        $people->bndroles()->detach();

        $people->bndroles()->attach($request->input('people.bndroles'));

        Toast::info(__('Person was saved'));

        (omissis)        

         return redirect()->route('platform.tables.people');   
    }

I see the problem when I try to remove last element on emails matrix field. This is my model:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

use Orchid\Filters\Filterable;
use Orchid\Metrics\Chartable;
use Orchid\Screen\AsSource;

use App\Orchid\Presenters\PeoplePresenter;

class People extends Model
{
    use HasFactory, AsSource, Filterable, Chartable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [" (all fillable fields) "];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        "phones" => "array",
        "emails" => "array",
        "socials" => "array",
        "bnd_roles" => "array",
        "birth_date" => "date",
        "is_family" => "boolean",
    ];

    /**
     * @var array
     */
    protected $allowedFilters = [
        (all filterable fields)
    ];

    /**
     * @var array
     */
    protected $allowedSorts = [
        (all sortable fields)
    ];

    public function presenter(): PeoplePresenter
    {
        return new PeoplePresenter($this);
    }

    (get, set and relations... omitted)
}

gioacchinopoletto avatar Aug 22 '22 07:08 gioacchinopoletto