Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[Bug] Relationship field not setting foreign key when having custom name #3058

Closed
rinodrummer opened this issue Jul 21, 2020 · 2 comments
Closed
Assignees
Labels

Comments

@rinodrummer
Copy link
Contributor

Bug report

Hi, I think that there is a problem with the relationship field when the foreign key has a custom name.
Here you can find some details about my problem.

Thanks in advice.

What I did

I have defined the field context_id in my consumers migration that reffers to users table.

Then I've defined my models

App\Models\User
<?php

namespace App\Models;

use Backpack\CRUD\app\Models\Traits\CrudTrait;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Notifications\Notifiable;

use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Laravel\Sanctum\HasApiTokens;

class User extends Model
{
    use HasApiTokens;
    use Notifiable;
    use SoftDeletes;

    use CrudTrait;

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

    public $identifiableAttribute = 'email';

    protected $table = 'users';

    protected $guarded = ['id'];

    protected $fillable = [
        'email',
        'password',
        'is_admin',
        'admin_notes'
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'is_admin' => 'boolean'
    ];

    protected $dates = [
        'first_login_at' => 'datetime',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
        'deleted_at' => 'datetime',
    ];

    //protected $with = ['profilable'];

    /**
     * Data that gets attached with attributes.
     *
     * @var array
     */
    protected $appends = [];

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

    // Other relations...

    public function consumers() {
        return $this->hasMany('App\Models\Consumer', 'context_id');
    }
}
App\Models\Consumer
<?php

namespace App\Models;

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

class Consumer extends Model
{
    use CrudTrait;

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

    protected $table = 'consumers';
    // protected $primaryKey = 'id';
    // public $timestamps = false;
    protected $guarded = ['id'];

    protected $fillable = [
        'title',
        'notes',
        'context_id',
        'context' // I know its useless here
    ];
    // protected $hidden = [];
    // protected $dates = [];

    // Other relations

    public function context() {
        return $this->belongsTo('App\Models\User', 'context_id');
    }
}

Then I proceeded to create my consumer request:

App\Requests\Http\ConsumerRequest
<?php

namespace App\Http\Requests;

use App\Http\Requests\Request;
use Illuminate\Foundation\Http\FormRequest;

class ConsumerRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        // only allow updates if the user is logged in
        return backpack_auth()->check();
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        if ($this->method() === 'POST') {
            dd($this->input());
        }

        return [
            'title' => 'string|required|min:5|max:255',
            'notes' => 'nullable|string',
            'context' => 'integer|exists:users,id',
            'context_id' => 'integer|exists:users,id'
        ];
    }


    public function attributes() {
        return [];
    }

    public function messages() {
        return [];
    }
}

And the respective controller:

App\Http\Controllers\Admin\ConsumerCrudController
<?php

namespace App\Http\Controllers\Admin;

use App\Helpers\RelationshipCrudHelper;
use App\Http\Requests\ConsumerRequest;
use Backpack\CRUD\app\Http\Controllers\CrudController;
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;

/**
 * Class ConsumerCrudController
 * @package App\Http\Controllers\Admin
 * @property-read \Backpack\CRUD\app\Library\CrudPanel\CrudPanel $crud
 */
class ConsumerCrudController extends CrudController
{
    use \Backpack\CRUD\app\Http\Controllers\Operations\ListOperation;
    use \Backpack\CRUD\app\Http\Controllers\Operations\InlineCreateOperation;
    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\Consumer::class);
        $this->crud->setRoute(config('backpack.base.route_prefix') . '/consumer');
        $this->crud->setEntityNameStrings('utenza', 'utenze');
    }
    
    protected function setupListOperation()
    {
        $this->crud->setFromDb();
    }

    /**
     * Define what happens when the Create operation is loaded.
     *
     * @see https://backpackforlaravel.com/docs/crud-operation-create
     * @return void
     */
    protected function setupCreateOperation()
    {
        $this->crud->setValidation(ConsumerRequest::class);

        $this->crud->addField([
            'name' => 'title',
            'label' => 'Titolo',
            'type' => 'text',
        ]);

        $this->crud->addField([
            'name' => 'notes',
            'label' => 'Note',
            'type' => 'textarea',
        ]);

        // *** This is the context relationship field
        $this->crud->addField([
            'name' => 'context',
            'entity' => 'context',
            'model' => 'App\Models\User',
            'type' => 'relationship',
            'label' => 'Utente (Contesto)',
            'placeholder' => 'Selezionare un contesto',
        ]);
    }

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

    protected function setupShowOperation()
    {
        $this->setupListOperation();
    }
}

What I expected to happen

That correctly creates the desired consumer instance, realting it to the right user specified by the field context_id.

What happened

I get this error:

Illuminate\Database\QueryException
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'context' in 'field list' (SQL: insert into `consumers` (`title`, `notes`, `context`, `updated_at`, created_at) values (Acquedotto 1, ?, 1, 2020-07-21 11:33:53, 2020-07-21 11:33:53))

Thesre are fields of the request:

array:6 [▼
  "_token" => "nnDzFuFc7KmSJv6HshZOyiGHGuongcFKoVuilzNi"
  "http_referrer" => "http://127.0.0.1:8000/app/consumer/create"
  "title" => "Acquedotto 1"
  "notes" => null
  "context" => "1"
  "save_action" => "save_and_back"
]

What I've already tried to fix it

I've tried various combinations and fields. The one that I published are the most generic ones.

Follows the most likely alternative of the field:

$this->crud->addField([
    'name' => 'context_id',
    'entity' => 'context',
    'model' => 'App\Models\User',
    'type' => 'relationship',
    'label' => 'Utente (Contesto)',
    'placeholder' => 'Selezionare un contesto',
]);

That returns this error:

Illuminate\Database\QueryException
SQLSTATE[HY000]: General error: 1364 Field 'context_id' doesn't have a default value (SQL: insert into `consumers` (`title`, `notes`, `updated_at`, `created_at`) values (Acquedotto 1, ?, 2020-07-21 11:42:10, 2020-07-21 11:42:10))

But the request stay the same.

Backpack, Laravel, PHP, DB version

When I run php artisan backpack:version the output is:

### PHP VERSION:
PHP 7.4.0 (cli) (built: Nov 27 2019 10:14:18) ( ZTS Visual C++ 2017 x64 )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.0, Copyright (c), by Zend Technologies

### LARAVEL VERSION:
v7.20.0@682ea946bc136aa686d5a64940ab3d4a24d5a613

### BACKPACK VERSION:
4.1.15@6c751de946a9c8511dd32eb7bfa3ca6a568849f5
@welcome
Copy link

welcome bot commented Jul 21, 2020

Hello there! Thanks for opening your first issue on this repo!

Just a heads-up: Here at Backpack we use Github Issues only for tracking bugs. Talk about new features is also acceptable. This helps a lot in keeping our focus on improving Backpack. If you issue is not a bug/feature, please help us out by closing the issue yourself and posting in the appropriate medium (see below). If you're not sure where it fits, it's ok, a community member will probably reply to help you with that.

Backpack communication channels:

  • Bug Reports, Feature Requests - Github Issues (here);
  • Quick help (How do I do X) - Gitter Chatroom;
  • Long questions (I have done X and Y and it won't do Z wtf) - Stackoverflow, using the backpack-for-laravel tag;
  • Showing off something you've made, asking for opinion on Backpack/Laravel matters - Reddit;

Please keep in mind Backpack offers no official / paid support. Whatever help you receive here, on Gitter, Slack or Stackoverflow is thanks to our awesome awesome community members, who give up some of their time to help their peers. If you want to join our community, just start pitching in. We take pride in being a welcoming bunch.

Thank you!

--
Justin Case
The Backpack Robot

@rinodrummer
Copy link
Contributor Author

rinodrummer commented Jul 21, 2020

I'm closing the issue as duplicated - see #2933

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants