I have created many to many relation using a pivot table, I can detach records using ->detach($id) which is fine, but when I try to attach:
$criteria->criterias()->attach($criteria_id);
I get this error:
Next exception 'Illuminate\Database\QueryException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`forge`.`criteria_criteria`, CONSTRAINT `criteria_criteria_criteria_id_foreign` FOREIGN KEY (`criteria_id`) REFERENCES `criterias` (`id`) ON DELETE CASCADE) (SQL: insert into `criteria_criteria` (`central_criteria_id`, `criteria_id`) values (11893, 8647))' in /home/forge/default/vendor/laravel/framework/src/Illuminate/Database/Connection.php:651
My models:
class Criteria extends Model {
protected $table = 'criterias';
public $timestamps = true;
public function criterias()
{
return $this->belongsToMany('App\Criteria', 'criteria_criteria', 'central_criteria_id', 'criteria_id');
}
}
class CriteriaCriteria extends Model {
protected $table = 'criteria_criteria';
}
And, here is my migrations for them:
class CreateCriteriasTable extends Migration {
public function up()
{
Schema::create('criterias', function(Blueprint $table) {
$table->increments('id');
$table->timestamps();
});
}
class CreateCriteriaCriteriaPivotTable extends Migration
{
public function up()
{
Schema::create('criteria_criteria', function(Blueprint $table) {
$table->integer('central_criteria_id')->unsigned()->index();
$table->foreign('central_criteria_id')->references('id')->on('criterias')->onDelete('cascade');
$table->integer('criteria_id')->unsigned()->index();
$table->foreign('criteria_id')->references('id')->on('criterias')->onDelete('cascade');
});
}
Any idea how to solve this?
Try adding ->unsigned()->index(); to your migration like this:
class CreateCriteriasTable extends Migration {
public function up()
{
Schema::create('criterias', function(Blueprint $table) {
$table->increments('id')->unsigned()->index();
$table->timestamps();
});
}
Related
When im trying to sync or attach in server side isn't working, here my models:
Migration Cuenta:
public function up()
{
Schema::create('cuentas', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->id();
$table->string('accountName');
$table->integer('potencialP');
$table->integer('potencialR');
$table->timestamps();
});
}
Cuenta Model:
class Cuenta extends Model
{
use HasFactory;
protected $fillable = ['id','accountName','potencialP','potencialR'];
public function options(){
return $this->belongsToMany('App\Models\Option','cuentas_options');
}
}
Migration Option:
public function up() {
Schema::create('options', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->id();
$table->string('titulo');
$table->integer('puntos');
$table->unsignedBigInteger('field_id');
$table->timestamps();
$table->foreign('field_id')->references('id')->on('fields');
});
}
Option Model:
class Option extends Model
{
use HasFactory;
protected $fillable = ['id'];
public function cuentas(){
return $this->belongsToMany('App\Models\Cuenta','cuentas_options');
}
}
Cuentas_option MIGRATION:
public function up()
{
Schema::create('cuentas_options', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->id();
$table->string('cuenta_id');
$table->unsignedBigInteger('option_id');
// $table->timestamps();
$table->foreign('cuenta_id')->references('id')->on('cuentas');
$table->foreign('option_id')->references('id')->on('options');
});
}
MyExampleCode:
$cuenta = Cuenta::find('8963596291');
$option = Option::all()->pluck('id');
$cuenta->options()->sync($option);
return $cuenta;
It returns:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`potencial_pr`.`cuentas_options`, CONSTRAINT `cuentas_options_cuenta_id_foreign` FOREIGN KEY (`cuenta_id`) REFERENCES `cuentas` (`id`)) (SQL: insert into `cuentas_options` (`cuenta_id`, `option_id`) values (8963596291, 1))
In my local server is working properly but not in server hosting, can someone help me?
EDIT:
IM USING LARAVEL 8, AND UPDATED THE CUENTAS_OPTIONS MIGRATIONS:
public function up()
{
Schema::create('cuentas_options', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->id();
$table->unsignedBigInteger('cuenta_id');
$table->unsignedBigInteger('option_id');
// $table->timestamps();
$table->foreign('cuenta_id')->references('id')->on('cuentas');
$table->foreign('option_id')->references('id')->on('options');
});
}
THE PROBLEM CONTINUE,
IM USING 10.4.11-MariaDB - mariadb.org binary distribution on local host and 5.6.49-cll-lve - MySQL Community Server (GPL) on server, could be this the problem?
I solved it by adding the KEYTYPE on the CUENTAS model and AUTO_INCREMENT=FALSE
The problem might be at $table->string('cuenta_id'); since on cuentas table you created the column as an ID, depending on your laravel version it might be an unsigned integer or an unsigned big integer
To the foreign keys works properly, you have to be sure that the columns related are exacly the same types, with the same charset and everything, in your case, on cuentas table you created it as an integer, an later o created the foreing key as an string
See Conditions and Restrictions for foreign keys here https://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html
Probably locally you're working with SQLITE that doesn't validate foreing keys in almost every case, try to create an mysql enviroment locally to work with the same aspects
I currently have a 1:1 relationship and I need it to be a one to many.
Such that Job Details can have multiple results for 1 Job Search.
Job Searches
public function up()
{
Schema::create('job_searches', function (Blueprint $table) {
$table->increments('id');
});
}
Job Details
public function up()
{
Schema::create('job_details', function (Blueprint $table) {
$table->integer('job_details_id',11);
$table->foreign('job_details_id')->references('id')->on('job_searches');
});
}
The current output I am getting is:
Job_Search_Id
1
Job_Detail_Id
1
When adding another result to the job details I get:
Illuminate\Database\QueryException with message 'SQLSTATE[23503]:
Foreign key violation: 7 ERROR: insert or update on table
"job_details" violates foreign key constraint
"job_details_job_details_id_foreign"
I also have stated the relationships in my models
Job Search Model
class JobSearches extends Model
{
protected $primaryKey = 'id';
public function job_details(){
return $this->belongsToMany('App\job_details');
}
}
Job Details Model
class JobDetails extends Model
{
protected $primaryKey = 'job_details_id';
public function job_search(){
return $this->hasOne('App\job_search');
}
Change the migration to:
public function up()
{
Schema::create('job_details', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('job_search_id');
});
Schema::table('job_details', function (Blueprint $table) {
$table->foreign('job_search_id')->references('id')->on('job_searches');
});
}
And the JobSearch class:
class JobSearch extends Model
{
public function jobDetails(){
return $this->hasMany('App\JobDetail');
}
}
And the JobDetail class:
class JobDetails extends Model
{
public function jobSearch()
{
return $this->belongsTo('App\JobSearch');
}
}
If you'll use the code without modification, it will work for you.
Hi so here are my relation:
Location:
public function _geoloc()
{
return $this->belongsTo('App\GeoLoc', 'id');
}
Geoloc:
public function locations()
{
return $this->hasOne('App\Location', 'geoloc_id');
}
Controller:
$geoloc = new Geoloc;
$geoloc->lat = $request->input('lat');
$geoloc->lng = $request->input('lng');
$geoloc->save();
$geoloc_id = $geoloc->id;
$location = new Location;
$location->business_id = $business_id;
$location->latitude = $request->input('lat');
$location->longitude = $request->input('lng');
$location->slug = $request->input('name');
$location->geoloc_id = $geoloc_id;
$location->save();
Full error message:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or
update a child row: a foreign key constraint fails
(liveoldham.locations, CONSTRAINT locations_geoloc_id_foreign
FOREIGN KEY (geoloc_id) REFERENCES geoloc (id) ON DELETE CASCADE
ON UPDATE CASCADE) (SQL: insert into locations (business_id,
latitude, longitude, slug, geoloc_id, updated_at,
created_at) values (1, 53.4867546, -2.054066599999942, Live & Now,
94, 2017-06-27 15:22:51, 2017-06-27 15:22:51))
All the values are correct, row is inserted into geoloc but it doesn't get inserted to locations and this is the error I am gettiing, how can that be fixed?
//edit:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateLocationsTable extends Migration {
public function up()
{
Schema::create('locations', function(Blueprint $table) {
$table->increments('id');
$table->integer('business_id')->unsigned();
$table->float('latitude', 10,6);
$table->float('longitude', 10,6);
$table->integer('geoloc_id')->unsigned();
$table->string('slug', 29)->nullable();
$table->timestamps();
});
}
public function down()
{
Schema::drop('locations');
}
}
2nd:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateGeolocTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('_geoloc', function(Blueprint $table) {
$table->increments('id');
$table->float('lat', 10,6);
$table->float('lng', 10,6);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('_geoloc');
}
}
You should use the associate method when updating a belongsTo relationship.
So, instead of
$location->geoloc_id = $geoloc_id;
Use
$location->_geoloc()->associate($geoloc);
$location->save();
Also make sure your belongsTo & hasOne have correct ForeignKey as second parameter.
According to your migration,
Your Location Model should have
public function _geoloc()
{
return $this->belongsTo('App\GeoLoc', 'geoloc_id');
}
Also, I don't see you setting a foreign key relationship using migration itself. So update your CreateLocationsTable to:
$table->integer('geoloc_id')->unsigned();
$table->foreign('geoloc_id')->references('id')->on('_geoloc')->onDelete('cascade');
Now you should re-run your migrations and it will work.
I have the following schema:
Schema::create('companies', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->timestamps();
});
Schema::create('departments', function (Blueprint $table) {
$table->increments('id');
$table->integer('company_id');
$table->string('name');
$table->timestamps();
$table->foreign('company_id')->references('id')->on('companies');
$table->unique(['company_id','name']);
});
Schema::create('employees', function (Blueprint $table) {
$table->increments('id');
$table->integer('company_id');
$table->string('name');
$table->timestamps();
$table->foreign('company_id')->references('id')->on('companies');
});
Schema::create('managed_departments', function (Blueprint $table) {
$table->integer('company_id');
$table->integer('department_id');
$table->integer('manager_id');
$table->timestamps();
$table->primary(['company_id','department_id']);
// Overlapping foreign keys guarantee that the manager
// and the department belong to the same company.
$table->foreign(['company_id','department_id'])
->references(['company_id','department_id'])
->on('departments');
$table->foreign(['company_id','manager_id'])
->references(['company_id','id'])
->on('employees');
});
Schema::create('department_staff', function (Blueprint $table) {
$table->integer('company_id');
$table->integer('department_id');
$table->integer('employee_id');
$table->timestamps();
$table->primary(['company_id','department_id', 'employee_id']);
// Overlapping foreign keys guarantees that the employee and the
// managed department belong to the same company.
$table->foreign(['company_id','department_id'])
->references(['company_id','department_id'])
->on('managed_departments');
$table->foreign(['company_id','employee_id'])
->references(['company_id','id'])
->on('employees');
});
Whats the correct model relationship between the departments, managed_departments and the department_staff tables in the
above schema - i'm a bit confused with how to define the relationship when there are composite primary keys and the following doesn't look right to me and how will eloquent know the correct foreign keys?
class Department extends Model
{
// a department is managed by an employee
public function managedDepartment
{
$this->hasOne(app\ManagedDepartment)
}
}
class ManagedDepartment extends Model
{
// a managed department belongs to department
public function Department
{
$this->belongsTo(app\Department)
}
// a managed department is managed by an employee
public function Employee
{
$this->belongsTo(app\Employee)
}
}
class DepartmentStaff extends Model
{
public function employee()
{
return $this->belongsTo('App\Employee');
}
}
class Employee extends Model
{
// an employee can managed many depts
public function managedDepartment
{
$this->hasMany(app\ManagedDepartment)
}
// an employee is asigned to one department
public function departmentStaff()
{
return $this->hasOne('App\DepartmentStaff');
}
}
I have the following Migrations:
Table: bebidas:
class CreateBebidasTable extends Migration{
public function up() {
Schema::create('bebidas', function ($table) {
$table->increments('id');
$table->integer('tipo_id')->unsigned();
$table->string('bebi_name');
$table->string('bebi_size');
$table->float('bebi_price');
$table->timestamps();
$table->foreign('tipo_id')->references('id')->on('tipobebidas');
});
}
public function down() {
Schema::drop('bebidas');
}
}
Table: tipobebidas
class CreateTiposBebidasTable extends Migration {
public function up()
{
Schema::create('tipobebidas', function($table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
public function down()
{
Schema::drop('tipobebidas');
}
}
These are the models:
class Bebida extends Eloquent{
public function TipoBebida() {
return $this->belongsTo('TipoBebida');
}
}
class TipoBebida extends Eloquent{
protected $table = "tipobebidas";
public function Bebidas() {
return $this->hasMany('Bebida');
}
}
Each Bebida (drink) has a TipoBebida (drink type) and vive-versa. I'm trying to get a composed table showing all fields from the bebidas table and tipobebidas table.
Based on Laravel's documentation on eager loading, I'm running the following command:
$bebidas = Bebida::with('tipobebida')->get();
At this point $bebidas has the following value: (I'm removing the timestamps fields)
[
{"id":1,"bebi_name":"COCA-COLA","bebi_size":"1 litro",
"bebi_price":4,"tipo_id":1,"tipobebida":null},
{"id":2,"bebi_name":"COCA ZERO","bebi_size":"1 litro",
"bebi_price":4,"tipo_id":1,"tipobebida":null}
]
Instead of "tipobebida":null, I was expecting something like "name":"refrigerantes" or some representation of the tipobebidas table contents.
I inspected the SQL commands being run, here it is:
select * from `tipobebidas` where `tipobebidas`.`id` in (?)
How can I get this to work?
I'll be using this data on a couple nested foreach loops to show the drinks Bebida grouped by type TipoBebida.
Thank you!
I got it to work. It all came down to naming conventions.
Here's what I did:
-The name of the foreign id field must be the singular of the table name plus _id, therefore the migration for bebidas was changed to the following:
class CreateBebidasTable extends Migration{
public function up() {
Schema::create('bebidas', function ($table) {
$table->increments('id');
$table->integer('tipobebida_id')->unsigned(); // ** new field name **
$table->string('name');
$table->string('size');
$table->float('price');
$table->timestamps();
});
}
public function down() {
Schema::drop('bebidas');
}
}
Also, the foreign key relationship was producing a SQL error, tried to fix it, still nothing, so I removed the following line: $table->foreign('tipo_id')->references('id')->on('tipobebidas');
Everything else remained unaltered.
The eager loading is working.
Thanks everyone for your help!!!
First, in tables bebidas and tipobebidas I don't see and foreign keys...
I think in bebidas you should have tipobebidas_id and it is a foreign key to tipobebidas id field.
After you do that, change your model methods to:
class Bebida extends Eloquent{
protected $table = "bebidas";
public function TipoBebida() {
return $this->belongsTo('TipoBebida', 'tipobebida_id');
}
}
class TipoBebida extends Eloquent{
protected $table = "tipobebidas";
public function Bebidas() {
return $this->hasMany('Bebida');
}