Using sync with many to many relationship in laravel: PostgreSQL Pivot table doesn't update - laravel

I'm getting this error whenever i try to sync an array of inputs to a pivot table:
Illuminate\Database\QueryException
SQLSTATE[23503]: Foreign key violation: 7 ERROR: insert or update on table "items_option_parcel"
violates foreign key constraint "items_option_id_fk_2971521" DETAIL: Key (items_option_id)=(0) is not present in table "items_options". (SQL: insert into "items_option_parcel" ("items_option_id", "parcel_id") values (0, 168))
here is a line of my controller:
$parcel->parcel_options()->sync($request->input('parcel_options', []));
function in the first model:
public function parcelOptionsParcels()
{
return $this->belongsToMany(Parcel::class);
}
function in the 2nd model:
public function parcel_options()
{
return $this->belongsToMany(ItemsOption::class);
}

I found out the issue, i checked my pluck() function, i forgot to pluck the items options ID with their SKUs, that's why every time it says a 0 id is not present in the table because it wasn't getting fetched at all.
I changed this:
$parcel_options = ItemsOption::all()>pluck('item_option_sku')>prepend(trans('global.pleaseSelect'), '');
to this
$parcel_options =
ItemsOption::all()->pluck('item_option_sku','id')->prepend(trans('global.pleaseSelect'), '');

Related

using observers to delete all relations in Laravel

My tables structure is :
Shopsidname
Productsidnameshop_id
Product_tagsidlabelvalueproduct_id
Problem is: I want to delete products and product tags on deleting shop
I made two Observers and registered both :
ShopObserver
ProductObserver
ShopObserver :
public function deleting(Shop $shop)
{
$shop->products()->delete();
}
ProductObserver :
public function deleting(Product $product)
{
$product->tags()->delete();
}
But I have following error :
"SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`tabadolha`.`product_tags`, CONSTRAINT `product_tags_product_id_foreign` FOREIGN KEY (`product_id`) REFERENCES `products` (`id`)) (SQL: delete from `products` where `products`.`shop_id` = 26 and `products`.`shop_id` is not null)"
I don't want to use nullOnDelete on my database. I want to delete it by observer.
Any way?
The problem is that your second observer of tags should be fired FIRST, and you can't specify the order of observers in Laravel.
What I would to is delete the tags in the same ShopObserver, before deleting the products, and not create a separate ProductObserver.
Something like:
$shop->products->each(function($product) {
$products->tags()->delete();
});
$shop->products()->delete();
Please test, not sure about the syntax, typed it with phone from my memory :)

Laravel has one through not returning correctly. always returning the first ID

I have a table that looks like this
ContractorDocuments Documents Documents_Category
user_id id id
documents_id documents__category_id name
I tried the following in my ContractorDocuments Model however it is always returning the first Document Category only.
public function Documents_Category() {
return $this->hasOneThrough(Documents_Category::class, Documents::class, 'documents__category_id', 'id', 'documents_id','documents__category_id');
}
documents__category_id == foreign key on Documents Table
id = foreign key on owners table(Documents_Category)
documents_id = local key on owners table(ContractorDocuments)
documents__category_id = local key on Documents table
Would appreciate any help. Thank you!
From ContractorDocuments to Documents_Category, you don't need hasOneThrough relationship since ContractorDocuments can only have one Documents_Category through belongsTo().
// ContractorDocuments model
public function documents()
{
return $this->belongsTo(Documents::class, 'documents_id');
}
And
// Documents model
public function documents_category()
{
return $this->belongsTo(Documents_Category::class, 'documents__category_id');
}
You can just call
$contractorDocuments->documents->documents_category;

Laravel Database Migration Column altered to Unique and Nullable causing error

I am attempting to integrate social logins with my existing laravel app. I am attempting to change email and password to nullable but I also need email to remain unique. On executing my migration I am getting an error for duplicate key name 'users_email_unique'
Laravel 5, already fixed the issue with enum I had for altering a column.
Schema::table('users', function (Blueprint $table) {
$table->string('email')->unique()->nullable()->change();
$table->string('password')->nullable()->change();
});
Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1061 Duplicate key name 'users_email_unique' (SQL: alter table users add unique users_email_unique(email))
Exception trace:
1 Doctrine\DBAL\Driver\PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1061 Duplicate key name 'users_email_unique'")
/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:119
2 PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1061 Duplicate key name 'users_email_unique'")
/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:117
Edit
If I remove Unique() from email, will it remain unique since that was previously set in a different migration?
You can change the uniqueness behaviour in a new migration by following below:
public function up()
{
Schema::table('contacts', function (Blueprint $table) {
$table->dropUnique(['email']);
});
}
/**
* Reverse the migrations.
*
*/
public function down()
{
Schema::table('contacts', function (Blueprint $table) {
$table->string('email')->unique()->change();
});
}
The Nullable() attribute will stay with the email column, since it was created with it.
It sound like the database is detecting a repeated value. That's impossible with nulls, so it could be an empty string maybe.
If that's the case, you can write a mutator function in your model to check if the value is empty and, set it to null before it goes to the database engine, like this:
public function setNameOfYourAttribute($value) {
if ( empty($value) ) {
$this->attributes['nameofyourattribute'] = NULL;
}
}
Hope it helps.
NOTE:
Full Documentation
Figured this out myself, as mentioned in the comment on the above answer.
Simply because the table was already created with unique() if I remove that it will allow the migration and will also persist the unique() functionality that was in the original User table migration.

LARAVEL hasManyThrough still using the ID as foreign key

Hi trying to get the rest day of a country. But I am getting error.
Basically here is the structure
Employee
has SITE,
Site
has REGION,
Region
has REST DAY
I have declared this on my Employee Model
public function restdays()
{
return $this->hasManyThrough('App\ref_restdays', 'App\ref_gacomsit', 'region', 'region');
}
But I get this error
[Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Conversion failed when converting the varchar value 'RUAE' to data type int. (SQL: select [ref_restdays].*, [ref_gacomsit].[region] from [ref_restdays] inner join [ref_gacomsit] on [ref_gacomsit].[id] = [ref_restdays].[region] where [ref_gacomsit].[region] in (855))
Apparently it using still the ID of my site masterfile where as I have declared to use the REGION foreign key.
Can anyone explain where is my mistake is? Appreciate for your help.
Turns out I don't need to use hasManyThrough. I've just declared hasMany on my site masterfile like so:
public function restdays()
{
return $this->hasMany( 'App\ref_restdays', 'region', 'region');
}
then I just use the nested eager loading on my query using dot syntax.
here is my final query, on the last line I just reference site.restdays to get the list of restdays.
$employees = hr_employee::select(
'hr_employee.id',
'empno',
'first_name',
'family_name',
'empstatus',
'empstatus_eff_date',
'contcatg_code',
'post_title_code',
'cs',
'group_initial_joined',
'returned_date',
'mcat2',
'othours1',
'othours2',
'othours3'
)
->where([
['empno','=',$empno]
])
->with(['catg', 'post', 'site.restdays'])
->get();

Eloquent Relation not returning errors or result

The following code does not return any error:
$exchange = Exchange::findOrFail(16);
dd($exchange->values);
The Exchange model has the following relation:
return $this->belongsTo(ExchangeValue::class, 'value', 'exchange_id');
The database schema is:
exchanges (id, type, title, description)
exchange_values (id, exchange_id, value)
Of course I've specified the database table in the ExchangeValue model because it doesn't follow the Laravel convention.
I have a record in the database with exchange_id 16 and it's returning null, without a query error or something.
What could be the issue?

Resources