【问题标题】:v4.1 HasMany/BelongsTo relationship field -- Column not found: 1054 Unknown columnv4.1 HasMany/BelongsTo 关系字段 -- 未找到列:1054 未知列
【发布时间】:2023-04-01 06:35:01
【问题描述】:

我正试图找出我在应该是一个简单的 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
        ]);
    }
}

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

但是,当我在选择以前创建的“网站”后尝试保存时,我得到一个查询异常:

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) 

这个“关系”字段不应该用 client_id 更新网站模型而不是客户模型吗?还是我对这里的 1-n 关系如何运作有根本的误解……

我做错了什么?

【问题讨论】:

    标签: laravel has-many belongs-to laravel-backpack


    【解决方案1】:

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

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

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

    我在我的客户模型中创建了一个 mutator

    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(),
            ],
            //...
        ]
    

    所以在你的情况下,你必须在你的客户端模型上创建一个方法:

    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 = [];
    

    希望这对您的情况有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-26
      • 2021-10-24
      • 2021-12-03
      • 2019-01-25
      • 1970-01-01
      • 1970-01-01
      • 2017-08-09
      相关资源
      最近更新 更多