v4.1 HasMany / BelongsTo关系字段—找不到列:1054未知列

问题描述 投票:0回答:1

我试图弄清楚我应该在一个简单的1-n关系字段中做错了什么。

我有一个具有多个“网站”的模型“客户”

在我的客户模型中:

<?php

namespace App\Models;

use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Database\Eloquent\Model;

class Client extends Model
{
    use CrudTrait;
    use Sluggable;

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

    protected $table = 'clients';
    // protected $primaryKey = 'id';
    // public $timestamps = false;
    protected $guarded = ['id'];
    // protected $fillable = [];
    // protected $hidden = [];
    // protected $dates = [];

    /*
    |--------------------------------------------------------------------------
    | FUNCTIONS
    |--------------------------------------------------------------------------
    */

    /*
    |--------------------------------------------------------------------------
    | RELATIONS
    |--------------------------------------------------------------------------
    */

    public function contacts()
    {
        return $this->belongsToMany(Contact::class);
    }

    public function websites()
    {
        return $this->hasMany(Website::class, 'client_id');
    }


    /*
    |--------------------------------------------------------------------------
    | SCOPES
    |--------------------------------------------------------------------------
    */

    /*
    |--------------------------------------------------------------------------
    | ACCESSORS
    |--------------------------------------------------------------------------
    */

    /*
    |--------------------------------------------------------------------------
    | MUTATORS
    |--------------------------------------------------------------------------
    */
    /**
     * Return the sluggable configuration array for this model.
     *
     * @return array
     */
    public function sluggable()
    {
        return [
            'slug' => [
                'source' => 'name'
            ]
        ];
    }
}

我的网站模型

<?php

namespace App\Models;

use Backpack\CRUD\app\Models\Traits\CrudTrait;
use Illuminate\Database\Eloquent\Model;
use Cviebrock\EloquentSluggable\Sluggable;

class Website extends Model
{
    use CrudTrait;
    use Sluggable;

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

    protected $table = 'websites';
    // protected $primaryKey = 'id';
    // public $timestamps = false;
    protected $guarded = ['id'];
    // protected $fillable = [];
    // protected $hidden = [];
    // protected $dates = [];

    /*
    |--------------------------------------------------------------------------
    | FUNCTIONS
    |--------------------------------------------------------------------------
    */

    /*
    |--------------------------------------------------------------------------
    | RELATIONS
    |--------------------------------------------------------------------------
    */
    public function client(){
        return $this->belongsTo('App\Models\Client');
    }

    /*
    |--------------------------------------------------------------------------
    | SCOPES
    |--------------------------------------------------------------------------
    */

    /*
    |--------------------------------------------------------------------------
    | ACCESSORS
    |--------------------------------------------------------------------------
    */

    /*
    |--------------------------------------------------------------------------
    | MUTATORS
    |--------------------------------------------------------------------------
    */
    /**
     * Return the sluggable configuration array for this model.
     *
     * @return array
     */
    public function sluggable()
    {
        return [
            'slug' => [
                'source' => 'name'
            ]
        ];
    }
}

在我的客户CRUD控制器中:

<?php

namespace App\Http\Controllers\Admin;

use App\Http\Requests\ClientRequest;
use App\Models\Client;
use App\Models\Contact;
use App\Models\Website;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;

/**
 * Class ClientCrudController
 * @package App\Http\Controllers\Admin
 * @property-read \Backpack\CRUD\app\Library\CrudPanel\CrudPanel $crud
 */
class ClientCrudController 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;

    use \Backpack\CRUD\app\Http\Controllers\Operations\FetchOperation;

    public function setup()
    {
        $this->crud->setModel('App\Models\Client');
        $this->crud->with('websites');
        $this->crud->setRoute(config('backpack.base.route_prefix') . '/client');
        $this->crud->setEntityNameStrings('client', 'clients');
    }

    protected function setupListOperation()
    {
        // TODO: remove setFromDb() and manually define Columns, maybe Filters
//        $this->crud->setFromDb();
        $this->crud->setColumns(['name', 'slug']);
    }

    protected function setupCreateOperation()
    {
        $this->crud->setValidation(ClientRequest::class);

        // TODO: remove setFromDb() and manually define Fields
//        $this->crud->setFromDb();

        $this->crud->addFields(
            [
                [
                    'name' => 'name',
                    'type' => 'text',
                    'label' => "Client name",
                    'tab' => 'Client info',
                ],
                [   // Checkbox
                    'name'  => 'is_active',
                    'label' => 'Active',
                    'type'  => 'checkbox',
                    'tab' => 'Client info',
                ],
                [
                    'name'  => 'description',
                    'label' => 'Description',
                    'type'  => 'summernote',
                    'options' => [
                        'height' => 300,
                    ], // easily pass parameters to the summernote JS initialization
                    'tab' => 'Client info',
                ],
                [
                    'name'          => 'address',
                    'label'         => 'Address',
                    'type'          => 'address_algolia',
                    'tab' => 'Client info',
                    // optional
                    'store_as_json' => true
                ],
                [
                    'type' => 'relationship',
                    'name' => 'contacts', // the method on your model that defines the relationship
                    'tab' => 'Client info',
                    // OPTIONALS:
                    'label' => "Client Contacts",
                    'attribute' => "full_name", // foreign key attribute that is shown to user (identifiable attribute)
                    'entity' => 'contacts', // the method that defines the relationship in your Model
                    'model' => "App\Models\Contact", // foreign key Eloquent model
                    'placeholder' => "Add a contact", // placeholder for the select2 input
                    'ajax'          => true,
                    'inline_create' => [
                        'entity' => 'contact', // you need to specify the entity in singular
                        'modal_class' => 'modal-dialog modal-xl', // use modal-sm, modal-lg to change width
                    ]

                ],

                [
                    'type' => "relationship",
                    'name' => 'websites', // the method on your model that defines the relationship
                    'tab' => 'Assets',
//                    // OPTIONALS:
//                    'label' => "Client Websites",
//                     'attribute' => "name", // foreign key attribute that is shown to user (identifiable attribute)
//                     'entity' => 'websites', // the method that defines the relationship in your Model
//                     'model' => \App\Models\Website::class, // foreign key Eloquent model
//                    'placeholder' => "Select websites", // placeholder for the select2 input
//                    'ajax'          => true,
//                    'pivot' => false,
//                    'inline_create' => [
//                        'entity' => 'website',
//                        'modal_class' => 'modal-dialog modal-xl', // use modal-sm, modal-lg to change width
//                    ] // you need to specify the entity in singular
                ]
            ]
        );

    }

    protected function setupUpdateOperation()
    {
        $this->setupCreateOperation();
    }

    public function fetchWebsites()
    {
        return $this->fetch(\App\Models\Website::class);
    }

    public function fetchContacts()
    {
//        return $this->fetch(\App\Models\Contact::class);
        return $this->fetch([
            'model' => \App\Models\Contact::class, // required
            'searchable_attributes' => ['first_name', 'last_name', 'description'],
            'query' => function($model) {
                return $model->where('is_active', 1);
            } // to filter the results that are returned
        ]);
    }
}

现在,当我取消注释“ inline_create”部分时,我可以成功显示CRUD,搜索已经创建的“网站”,并添加“网站”。

但是,当我选择先前创建的“网站”后尝试保存时,出现查询异常:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'websites' in 'field list' (SQL: update `clients` set `websites` = ["1"], `clients`.`updated_at` = 2020-06-04 15:52:49 where `id` = 1) 

此“ relationship”字段是否应使用client_id更新网站模型,而不更新Clients模型?还是我对1-n关系在这里的工作方式有基本的误解...

我在做什么错?

laravel has-many belongs-to backpack-for-laravel
1个回答
0
投票

只是背包的新手我有一些类似的问题。DB是:客户有很多地址(1-n)当我编辑客户时,可以编辑多个地址。 (添加/编辑/删除)

受此问题启发:https://github.com/Laravel-Backpack/CRUD/issues/2729

仅供参考:我的显示方法和解决方案:ListEntries in table for relationship on show page - backpack for laravel

我已经在我的客户模型中创建了一个可变器

public function setAddressesAttribute($value) {
    $data = (json_decode($value, true)); //converts json into array
    $keys = self::addresses()->get()->modelKeys();


    //Insertar o actualizar registros en parent
    if(is_array($data)) {
        foreach ($data as $entry) {
            if (!empty($entry['address1'])) {
                $id = (int) $entry['id'];
                unset($entry['id']);
                if (($key = array_search($id, $keys)) !== false) 
                    unset($keys[$key]);  
                self::addresses()->updateOrCreate(['id' => $id], $entry);
            }
        }
    }
    //Eliminar registros en parent
    if(!empty($keys)) {
        foreach ($keys as $id) 
            self::addresses()->find($id)->delete();
    }    
}

以及在我的CustomerCrudController中,在setupCreateOperation方法中,我添加了那些字段:

    'addresses'=>[
        //...
        [
            'name' => 'id',
            'type' => 'hidden',
        ],
        [
            'name' => 'user_id',
            'type' => 'hidden',
            'default'   =>  CRUD::getCurrentEntryId(),
        ],
        //...
    ]

因此,在您的情况下,您必须在Client模型上创建一个方法:

public function setWebsitesAttribute($value) {
    $data = (json_decode($value, true)); //converts json into array
    $keys = self::websites()->get()->modelKeys();


    //Insertar o actualizar registros en parent
    if(is_array($data)) {
        foreach ($data as $entry) {
            if (!empty($entry['address1'])) {
                $id = (int) $entry['id'];
                unset($entry['id']);
                if (($key = array_search($id, $keys)) !== false) 
                    unset($keys[$key]);  
                self::websites()->updateOrCreate(['id' => $id], $entry);
            }
        }
    }
    //Eliminar registros en parent
    if(!empty($keys)) {
        foreach ($keys as $id) 
            self::websites()->find($id)->delete();
    }    
}

在您的网站模型中,您必须正确填写数组:

   protected $fillable = [];

希望这对您有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.