Laravel рюкзак select_multiple | select2_multple разрывается при обновлении / редактировании с отношением один ко многим - PullRequest
1 голос
/ 24 апреля 2020

Я столкнулся со странной ошибкой / проблемой на мой взгляд при обновлении (целевой) модели с помощью BackpackCrudController.

Сначала позвольте мне дать вам некоторую информацию о структуре и моделях моей базы данных. (я исключил бесполезные отношения и функции)

quick gr asp из моей composer. json

        "php": "^7.2",
        "backpack/crud": "4.0.*",
        "backpack/logmanager": "^3.0",
        "backpack/pagemanager": "^2.0",
        "backpack/permissionmanager": "^5.0",
        "fideloper/proxy": "^4.0",
        "laravel/framework": "^6.2",
        "laravel/tinker": "^2.0"

таблицы рецептов:

        Schema::create('recipes', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->string('slug');
            $table->string('image');
            $table->text('content');
            $table->text('preparation');
            $table->json('ingredients');
            $table->integer( 'goal_id')->unsigned()->nullable();
            $table->integer( 'category_id')->unsigned()->nullable();
            $table->unsignedBigInteger( 'user_id');
            $table->timestamps();
        });

        Schema::table('recipes', function(Blueprint $table) {
            $table->foreign( 'goal_id')->references( 'id')->on('goals');
            $table->foreign( 'category_id')->references( 'id')->on('categories');
            $table->foreign( 'user_id')->references( 'id')->on('users');
        });

таблица целей:

       Schema::create('goals', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->string('slug');
            $table->string('image');
            $table->text( 'content');
            $table->string('workbook')->nullable();
            $table->tinyInteger('duration')->nullable();
            $table->timestamps();
        });

Модель рецепта:

class Recipe extends Model
{
    use CrudTrait;
    use Sluggable;
    use SluggableScopeHelpers;

    /*
    |--------------------------------------------------------------------------
    | GLOBAL VARIABLES
    |--------------------------------------------------------------------------
    */

    protected $table = 'recipes';
    protected $guarded = ['id'];
    protected $fillable = ['title', 'slug', 'image', 'content', 'preparation', 'ingredients', 'goal_id', 'category_id', 'user_id'];


    /*
    |--------------------------------------------------------------------------
    | RELATIONS
    |--------------------------------------------------------------------------
    */
    public function goal(  ) {
        return $this->belongsTo( Goal::class);
    }
}

Модель цели:

class Goal extends Model
{
    use CrudTrait;
    use Sluggable;
    use SluggableScopeHelpers;

    /*
    |--------------------------------------------------------------------------
    | GLOBAL VARIABLES
    |--------------------------------------------------------------------------
    */

    protected $table = 'goals';
    protected $guarded = ['id'];
    protected $fillable = ['title', 'slug', 'image', 'content', 'workbook', 'duration'];


    /*
    |--------------------------------------------------------------------------
    | RELATIONS
    |--------------------------------------------------------------------------
    */
    public function recipes(  ) {
        return $this->hasMany( Recipe::class,'goal_id', 'id');
    }
}

Проблема существует при обновлении цели, поэтому вот мой GoalCrudController :

class GoalCrudController extends CrudController
{
    use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;

    public function setup()
    {
        $this->crud->setModel('App\Models\Goal');
        $this->crud->setRoute(config('backpack.base.route_prefix') . '/goal');
        $this->crud->setEntityNameStrings('goal', 'goals');
    }

    protected function setupCreateOperation()
    {
        $this->crud->setValidation(GoalRequest::class);
        $this->crud->addField([
            'label'     => 'Articles',
            'type'      => 'select2_multiple',
            'name'      => 'articles',
            'entity'    => 'articles',
            'attribute' => 'title',
        ]);
        $this->crud->addField([
            'label'     => 'Recipes',
            'type'      => 'select2_multiple',
            'name'      => 'recipes',
            'entity'    => 'recipes',
            'attribute' => 'title',
        ]);
    }

    protected function setupUpdateOperation()
    {
        $this->setupCreateOperation();
        $this->crud->removeField('image');
        $this->crud->addField([
            'name'      => 'image',
            'label'     => 'Image',
            'type'      => 'image',
            'upload'    => true,
            'prefix'    => 'uploads/',
        ])->afterField('title');
    }
}

Опять же, я пропустил функции, не предназначенные для этой проблемы.

Теперь проблема в том, что когда я создаю цель, я могу прикрепить рецепт (из поля select2_multiple ) и связь между целью и рецептом будет создана. Хотя, когда я хочу отредактировать / обновить цель, которую я только что создал, например, чтобы добавить новый рецепт, я получаю следующее исключение:

Exception
Property [recipes] does not exist on this collection instance.

Я попытался отредактировать поле в setupUpdateOperation() на следующее:

        $this->crud->removeField('recipes');
        $this->crud->addField([
            'label'     => 'Recipes',
            'type'      => 'select2_multiple',
            'name'      => 'recipes',
            'entity'    => 'recipes',
            'attribute' => 'title',
            'value'     => Recipe::where('goal_id', $this->crud->getCurrentEntryId()), // <-- added this
        ]);

Но тогда я получаю следующее исключение:

Call to a member function pluck() on string (View: /Users/name/Docker/sitename/vendor/backpack/crud/src/resources/views/crud/fields/select_multiple.blade.php) // <-- at line 27

Мои вопросы сейчас на самом деле:

  • Как я буду в состоянии позволить пользователю обновить существующую цель, чтобы добавить новые рецепты?
  • Кроме того, как возможно, что это работает при создании, но не когда я хочу обновить?
  • Использую ли я select_multiple | select2_multiple неправильно в этом случае?
  • Мои отношения неверны?
  • Не могу ли я сохранить отношение таким образом? И нужно ли мне делать это с конца рецепта?
  • Должен ли я использовать другое поле выбора для операции обновления или функции model_function?

Если мне нужно предоставить больше информации, пожалуйста, дайте мне знать, и я буду рад предоставить его для вас. Заранее спасибо!

PS. Проблема та же при использовании select_multiple.

1 Ответ

0 голосов
/ 05 мая 2020

Немного покопавшись, мне удалось найти решение.

В функции setupUpdateOperation я добавил следующее:

$this->crud->removeField('recipes'); // remove the original field
$this->crud->addField([
            'label'     => 'Recipes',
            'type'      => 'select2_multiple',
            'name'      => 'recipes',
            'entity'    => 'recipes',
            'attribute' => 'title',
            'value'     => $this->crud->getCurrentEntry()->recipes,
        ]);

С этим мне удалось получить текущий связанные рецепты в представлении обновления и фактически обновляют связанные рецепты.

...