Laravel Create Eloquent Instance from ManyToOne Relationship Error SQLSTATE[23000] - php

I want to create instance using Laravel 5 Eloquent Relationship.
I have 2 Migrations and 2 Eloquent Model.
Companies Migration:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCompaniesTable extends Migration {
public function up()
{
Schema::create('Companies', function(Blueprint $table)
{
$table->string('CompanyCode', 15);
$table->string('Name', 200);
$table->string('Type', 100);
$table->tinyInteger('IsActive')->default(1);
$table->timestamps();
$table->primary('CompanyCode');
});
}
public function down()
{
Schema::drop('Companies');
}
}
Company Model:
namespace App\Models\Setting\Organization;
use Illuminate\Database\Eloquent\Model;
class Company extends Model {
protected $fillable = ['CompanyCode', 'Name', 'Type'];
public function organizationUnits(){
return $this->hasMany('App\Models\Setting\Organization\OrganizationUnit', 'CompanyCode');
}
}
OrganizationUnits Migration:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateOrganizationUnitsTable extends Migration {
public function up()
{
Schema::create('OrganizationUnits', function(Blueprint $table)
{
$table->string('OrganizationUnitCode', 15); //PK
$table->string('CompanyCode', 15); //FK
$table->string('Name', 200);
$table->tinyInteger('IsActive')->default(1);
$table->timestamps();
$table->primary('OrganizationUnitCode');
$table->foreign('CompanyCode', 'OrgUnits_Company_FK')
->references('CompanyCode')
->on('Companies')
->onDelete('cascade');
});
}
public function down()
{
Schema::drop('OrganizationUnits');
}
}
OrganizationUnit Model:
namespace App\Models\Setting\Organization;
use Illuminate\Database\Eloquent\Model;
class OrganizationUnit extends Model {
protected $table = "OrganizationUnits";
protected $fillable = ['OrganizationUnitCode', 'CompanyCode', 'Name'];
public function company(){
return $this->belongsTo('App\Models\Setting\Organization\Company', 'CompanyCode');
}
}
The relationship is one Company may have one or more OrganizationUnit, one OrganizationUnit must have one and only one Company.
I tried to create new instance of OrganizationUnit in php artisan tinker using this code:
$company = \App\Models\Setting\Organization\Company::first();
$orgunit = $company->organizationUnits()->create(['OrganizationUnitCode' => 'abcdef']);
But Laravel gives the following error:
Illuminate\Database\QueryException with message 'SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'CompanyCode' cannot be null (SQL: insert into `OrganizationUnits` (`Org
anizationUnitCode`, `CompanyCode`, `updated_at`, `created_at`) values (abcdef, , 2015-12-17 00:17:33, 2015-12-17 00:17:33))'
Where did I go wrong? Please help. I'm new to Laravel.

It clearly says that CompanyCode cannot be null. You can define it by hand or you can use the increments method on the Blueprint instance while creating your migration.

Related

Spatie / Permissions throwing constraint failure when assigning Roles using UUID

I have a Laravel 9 project where I am using UUID's. I have just installed the Spatie Permissions package and followed the instructions to use it with UUID's ... But when I try to assignRole I am getting the following error;
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`project`.`model_has_roles`, CONSTRAINT `model_has_roles_role_id_foreign` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE) (SQL: insert into `model_has_roles` (`model_id`, `model_type`, `role_id`) values (1d6535d1-01f0-43b4-8701-4e3c76ad1587, App\Models\User, 0))
I think it might be something to do with the Spatie migration which comes with the package. I have updated it as per https://spatie.be/docs/laravel-permission/v5/advanced-usage/uuid#content-migrations .. as below;
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Spatie\Permission\PermissionRegistrar;
class CreatePermissionTables extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
$tableNames = config('permission.table_names');
$columnNames = config('permission.column_names');
$teams = config('permission.teams');
if (empty($tableNames)) {
throw new \Exception('Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.');
}
if ($teams && empty($columnNames['team_foreign_key'] ?? null)) {
throw new \Exception('Error: team_foreign_key on config/permission.php not loaded. Run [php artisan config:clear] and try again.');
}
Schema::create($tableNames['permissions'], function (Blueprint $table) {
$table->uuid('id'); // permission id
$table->string('name'); // For MySQL 8.0 use string('name', 125);
$table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125);
$table->timestamps();
$table->primary('id');
$table->unique(['name', 'guard_name']);
});
Schema::create($tableNames['roles'], function (Blueprint $table) use ($teams, $columnNames) {
$table->uuid('id'); // role id
if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing
$table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable();
$table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index');
}
$table->string('name'); // For MySQL 8.0 use string('name', 125);
$table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125);
$table->timestamps();
$table->primary('id');
if ($teams || config('permission.testing')) {
$table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']);
} else {
$table->unique(['name', 'guard_name']);
}
});
Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) {
$table->uuid(PermissionRegistrar::$pivotPermission);
$table->string('model_type');
$table->uuid($columnNames['model_morph_key']);
$table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index');
$table->foreign(PermissionRegistrar::$pivotPermission)
->references('id') // permission id
->on($tableNames['permissions'])
->onDelete('cascade');
if ($teams) {
$table->unsignedBigInteger($columnNames['team_foreign_key']);
$table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index');
$table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotPermission, $columnNames['model_morph_key'], 'model_type'],
'model_has_permissions_permission_model_type_primary');
} else {
$table->primary([PermissionRegistrar::$pivotPermission, $columnNames['model_morph_key'], 'model_type'],
'model_has_permissions_permission_model_type_primary');
}
});
Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) {
$table->uuid(PermissionRegistrar::$pivotRole);
$table->string('model_type');
$table->uuid($columnNames['model_morph_key']);
$table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index');
$table->foreign(PermissionRegistrar::$pivotRole)
->references('id') // role id
->on($tableNames['roles'])
->onDelete('cascade');
if ($teams) {
$table->unsignedBigInteger($columnNames['team_foreign_key']);
$table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index');
$table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotRole, $columnNames['model_morph_key'], 'model_type'],
'model_has_roles_role_model_type_primary');
} else {
$table->primary([PermissionRegistrar::$pivotRole, $columnNames['model_morph_key'], 'model_type'],
'model_has_roles_role_model_type_primary');
}
});
Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames) {
$table->uuid(PermissionRegistrar::$pivotPermission);
$table->uuid(PermissionRegistrar::$pivotRole);
$table->foreign(PermissionRegistrar::$pivotPermission)
->references('id') // permission id
->on($tableNames['permissions'])
->onDelete('cascade');
$table->foreign(PermissionRegistrar::$pivotRole)
->references('id') // role id
->on($tableNames['roles'])
->onDelete('cascade');
$table->primary([PermissionRegistrar::$pivotPermission, PermissionRegistrar::$pivotRole], 'role_has_permissions_permission_id_role_id_primary');
});
app('cache')
->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null)
->forget(config('permission.cache.key'));
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
$tableNames = config('permission.table_names');
if (empty($tableNames)) {
throw new \Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.');
}
Schema::drop($tableNames['role_has_permissions']);
Schema::drop($tableNames['model_has_roles']);
Schema::drop($tableNames['model_has_permissions']);
Schema::drop($tableNames['roles']);
Schema::drop($tableNames['permissions']);
}
}
I have a trait for UUID which is as follows;
<?php
declare(strict_types=1);
namespace App\Concerns;
use Illuminate\Support\Str;
trait HasUuid
{
protected static function boot(): void
{
parent::boot();
static::creating(function ($model) {
if (empty($model->{$model->getKeyName()})) {
$model->{$model->getKeyName()} = Str::uuid()->toString();
}
});
}
public function getIncrementing(): bool
{
return false;
}
public function getKeyType(): string
{
return 'string';
}
}
I have this on my User model, and also I have extended the Role and Permission model which now looks like this;
<?php
declare(strict_types=1);
namespace App\Models;
use App\Concerns\HasUuid;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Spatie\Permission\Models\Role as SpatieRole;
class Role extends SpatieRole
{
use HasFactory;
use HasUuid;
}
The code that it is failing on is the following which is a standard user create, but the assignRole is where it seems to be failing;
User::create([
'name' => 'Super Admin',
'email' => 'super-admin#example.com',
'password' => Hash::make('password'),
])->assignRole('super-admin');
Any help would be greatly appreciated.
I managed to figure this out if anyone has the same issue.
As I am extending the Role and Permission model, this needs to be reflected in the config/permission.php file
'models' => [
/*
* When using the "HasPermissions" trait from this package, we need to know which
* Eloquent model should be used to retrieve your permissions. Of course, it
* is often just the "Permission" model but you may use whatever you like.
*
* The model you want to use as a Permission model needs to implement the
* `Spatie\Permission\Contracts\Permission` contract.
*/
'permission' => \App\Models\Permission::class,
/*
* When using the "HasRoles" trait from this package, we need to know which
* Eloquent model should be used to retrieve your roles. Of course, it
* is often just the "Role" model but you may use whatever you like.
*
* The model you want to use as a Role model needs to implement the
* `Spatie\Permission\Contracts\Role` contract.
*/
'role' => \App\Models\Role::class,
],

"laravel Migration Foreign key constraint is incorrectly formed"

I have a problem In Laravel and I do not know where the problem is. someone can help me . And thank you in advance.
I have two tables (clients, and reparations)
I want to make a foreign key with the string field ('cin_client'), when I create the table reparations it does not work anymore
/* ************* table clients **************>
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateClientsTable extends Migration
{
public function up()
{
Schema::create('clients', function (Blueprint $table) {
$table->Increments('id_client');
$table->string('nom_client');
$table->string('prenom_client');
$table->string('adresse_client');
$table->string('tel_client');
$table->string('cin_client',30);
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('clients');
}
}
/************* Table reparations *************/
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateReparationsTable extends Migration
{
public function up()
{
Schema::create('reparations', function (Blueprint $table) {
$table->Increments('id_reparation');
$table->string('type_reparation')->nullable();
$table->string('date_reparation')->nullable();
$table->integer('prix_reparation')->nullable();
$table->string('genre_marque_type')->nullable();
$table->boolean('etat_reparation')->nullable();
/*$table->foreign('client_cin')->references('cin_client')->on('clients');*/
$table->timestamps();
$table->string('client_cin',30);
});
Schema::table('reparations', function (Blueprint $table){
$table->foreign('client_cin')->references('cin_client')->on('clients');
});
}
public function down()
{
Schema::dropIfExists('reparations');
}
}
So, that database error almost always means that the column you've defined to hold the foreign key reference in the first table, and the column you've defined in the second table are not matching formats or lengths. Looking at the migration (and not being sure what DBS you're using) I think you need to remove ->unsigned() from the column definition for reparations.client_cin.

HasOne create not updating foreign field

I'm using Laravel and I'm trying to create a related record from an array using the method HasOne::create. It inserts the related record, but does not add a new id to main model's foreign field. What am I doing wrong?
Thx
$contact = new Contact();
$contact->company = $data['company'] ?? '';
$contact->comment = $data['comment'] ?? '';
$contact->save();
$contact->address()->create($data['address']);
...
var_dump($contact->address_id); exit();
The relations work fine, all fields specified. By ->get() methods they're returning correct models
var_dump result - null
Also, the $data['address'] contains valid data, specified as fillable at Address model and address_id is fillable for Contact model
UPD:
Contact class:
public function address()
{
return $this->hasOne(Address::class, 'id', 'address_id');
}
Address class:
public function contact()
{
return $this->belongsTo(Contact::class, 'id', 'address_id');
}
$data['address'] contains an array with ['raw' => 'someaddress'], raw field is in $fillable
There's a nice guide on Eloquent Relationships here.
Based on that I just tested the code below and it works fine (using Laravel 5.8)
Migration
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class Cars extends Migration
{
public function up()
{
Schema::create('owners', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
Schema::create('cars', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
$table->integer('owner_id')->unsigned()->index()->nullable();
$table->foreign('owner_id')->references('id')->on('owners');
});
}
public function down()
{
Schema::drop('cars');
Schema::drop('owners');
}
}
Models
//App/Owner.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Owner extends Model
{
protected $fillable = ['name'];
public function car()
{
return $this->hasOne(Car::class);
}
}
//App/Car.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Car extends Model
{
protected $fillable = ['name'];
public function owner()
{
return $this->belongsTo(Owner::class);
}
}
Test
<?php
namespace Tests\Feature;
use App\Owner;
use Tests\TestCase;
class TestCars extends TestCase
{
/**
* A basic feature test example.
*
* #return void
*/
public function testExample()
{
$owner = new Owner(['name' => 'Jack']);
$owner->save();
$owner->car()->create(['name' => 'Nice Car']);
}
}
SQL
select * from cars;
------------
# id, name, created_at, updated_at, owner_id
'1', 'Nice Car', '2019-06-21 13:08:58', '2019-06-21 13:08:58', '1'
select * from owners
-------------
# id, name, created_at, updated_at
'1', 'Jack', '2019-06-21 13:08:58', '2019-06-21 13:08:58'

Laravel 4.2 and migrate make not working

I create a project based on the book Getting Started with Laravel 4.
So, I create two files in app/models/ - Cat.php and Breed.php with this content:
Cat.php
<?php
class Cat extends Eloquent {
protected $fillable = array('name','date_of_birth','breed_id');
public function breed() {
return $this->belongsTo('Breed');
}
}
and Breed.php
<?php
class Breed extends Eloquent {
public $timestamps = false;
public function cats()
{
return $this->hasMany('Cat');
}
}
and after, I use command php artisan migration:make create_cats_and_breeds_table
Ok, and should arise file in app/database/migrations. It is.
But, its contents it's not same as in the book...
In book:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddCatsAndBreedsTable extends Migration {
public function up()
{
Schema::create('cats', function($table)
{
$table->increments('id');
$table->string('name');
$table->date('date_of_birth');
$table->integer('breed_id')->nullable();
$table->timestamps();
})
Schema::create('breeds', function($table)
{
$table->increments('id');
$table->string('name');
})
}
public function down()
{
Schema::drop('cats');
Schema::drop('breeds');
}
}
My code:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddCatsAndBreedsTable extends Migration {
public function up()
{
//
}
public function down()
{
//
}
}
What's happen?
https://github.com/laracasts/Laravel-4-Generators
Provides some additional artisan commands which you can used to specific your fields in order to generate the migration files.
php artisan generate:migration create_posts_table --fields="title:string, body:text"
migration:make command does not know anything about your models. It just creates a stub that you need to fill with column definitions for your tables.

BadMethodCallException with eager loading in Laravel 4

I have two models User.php and Blog.php and the content,
Model User.php
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
protected $softDelete = true;
protected $table = 'users';
protected $hidden = array('password');
//-----
public function blogs()
{
return $this->has_many('Blog');
}
//----
Model Blog.php
<?php
class Blog extends Eloquent {
protected $guarded = array();
public static $rules = array();
public function author()
{
return $this->belongs_to('User', 'author_id');
}
}
The Controller, BlogsController.php
<?php
class BlogsController extends BaseController {
public function index()
{
$posts = Blog::with('author')->get();
return Response::json(array(
'status' => 'success',
'message' => 'Posts successfully loaded!',
'posts' => $posts->toArray()),
200
);
}
//-----
The blogs schema,
Schema::create('blogs', function(Blueprint $table) {
$table->increments('id');
$table->string('title');
$table->text('body');
$table->integer('author_id');
$table->timestamps();
$table->softDeletes();
});
And the users schema,
Schema::create('users', function(Blueprint $table) {
$table->integer('id', true);
$table->string('name');
$table->string('username')->unique();
$table->string('email')->unique();
$table->string('password');
$table->timestamps();
$table->softDeletes();
});
When I call Blog::with('author')->get(); from BlogsController, I am getting this error:-
"type":"BadMethodCallException","message":"Call to undefined method Illuminate\\Database\\Query\\Builder::belongs_to()"
And when I change Blog::with('author')->get(); to Blog::with('author')->all();, the error become:-
"type":"BadMethodCallException","message":"Call to undefined method Illuminate\\Database\\Query\\Builder::all()"
I am using latest update for Laravel 4. What is the wrong with my code?
Your going to love and hate this answer, change belongs_to to belongsTo. Same goes for has_many to hasMany and has_one to hasOne.
Laravel 4 moved to using camel case for methods. Your method not being found on the eloquent model, it falls back to calling it on the query builder, laravel does this to allow short cutting to methods like select() and where().
The second error you were getting, when using all(), is because all() is a static method defined on eloquent and does not work with eager loading. get() is effectively the same thing as all().

Categories