4

I'm using Backpack for Laravel as my back-end for managing entities. I have a 'show' entity, which is defined as such:

public function up()
    {
        Schema::create('shows', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('category_id')->nullable();
            $table->string('title');


            // Created/modified timestamps
            $table->timestamps();

        });

        // Add our search indexes
        DB::statement('ALTER TABLE shows ADD searchable tsvector NULL');
        DB::statement('CREATE INDEX shows_index ON shows USING GIN (searchable)');
    }

As you can see there is a 'searchable' column which is a tsvector. This is important for my Postgres FTS.

Within the CrudController for the show entity, I manually define the following, for my title and category_id fields:

// Title
$this->crud->addField([
    'name' => 'title',
    'label' => 'Show Title',
    'type' => 'text'
]);
$this->crud->addColumn([
    'name' => 'title',
    'label' => 'Title'
]);



// Assigned category ID
$this->crud->addField([ // Select2Multiple = n-n relationship (with pivot table)
    'label' => "Assign to Category",
    'type' => 'select2',
    'name' => 'category_id', // the db column for the foreign key
    'entity' => 'category', // the method that defines the relationship in your Model
    'attribute' => 'title', // property from the model that is shown to user
    'model' => "App\Models\Category", // foreign key model
    'data_source' => url("admin/category")
]);
$this->crud->addColumn([
    'name' => 'category_id', // The db column name
    'label' => "Category", // Table column heading
    'type' => 'select',
    'entity' => 'category',
    'model' => "App\Models\Category",
    'attribute' => 'title'
]);

The problem is the category_id field. Though it has nothing to do with the searchable tsvector field, it appears that the 'select2' type is looking at all my columns for some reason, seeing the tsvector type of my 'searchable' column, and breaking anytime I go to edit a show. I can see the show index page within Backpack just fine, but when I click edit on a specific show, I get the following error:

Unknown database type tsvector requested, Doctrine\DBAL\Platforms\PostgreSQL92Platform may not support it. (View: resources/views/vendor/backpack/crud/fields/select2.blade.php)

If I instead try to display the category_id field as a simple text type, I get no error and it works correctly:

$this->crud->addField([
            'name' => 'category_id',
            'label' => 'Category ID',
            'type' => 'text'
        ]);
        $this->crud->addColumn([
            'name' => 'category_id',
            'label' => 'Category ID'
        ]);

It seems very strange to me that although I'm defining my fields manually in my CrudController, rather than pulling every field from the database, and although I'm not referencing my 'searchable' field in any way here for the select2, it's still looking at my 'searchable' column, seeing the tsvector type, and giving up on me.

EDIT:

I've traced the issue to resources/views/vendor/backpack/crud/fields/select2.blade.php, specifically this chunk of code:

@if ($entity_model::isColumnNullable($field['name']))
            <option value="">-</option>
        @endif

If I comment these three lines out, everything loads fine. Despite $field['name'] being 'category_id' and not the tsvector 'searchable' field, for some reason checking if it's nullable breaks the whole thing. I've yet to trace this any further.

carbide20
  • 1,717
  • 6
  • 29
  • 52

1 Answers1

3

I found a solution myself for this. As doctrine is unaware of the tsvector type, it needed to be registered within vendor/backpack/crud/src/CrudTrait.php

Within the isColumnNullable() function, there is already an example of a different unsupported field type (enum) being cast to a string:

// register the enum column type, because Doctrine doesn't support it
        $conn->getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');

I simply added the tsvector type after that, and everything works correctly now:

// register the tsvector column type, because Doctrine doesn't support it
        $conn->getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('tsvector', 'string');
carbide20
  • 1,717
  • 6
  • 29
  • 52