laravel pivot table with nullable foreign key - mysql

I have a pivot table set up as follows:
user_roles
user_id //fk->users.id
assoc_id //nullable fk->association.id
role //varchar
I set my database up this way because roles represent a many to many relationship: an association has many users, and a user may be in many associations. every user has a role within an association.
However, there are some roles that exist that can exist outside of an association. The database is configured to accept a null value in the assoc_id field and I can manually insert one from the command line, but when I attempt to execute
$user->roles()->attach(NULL, "outside contractor");
in my seed file, I get an error saying
[Illuminate\Database\QueryException]
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update
a child row: a foreign key constraint fails (`database`.`user_roles`, CONSTR
AINT `user_roles_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users
` (`id`)) (SQL: insert into `user_roles` () values ())
this is particularly confusing because shouldn't the first argument here be referring to the assoc_id? When I replace the NULL with a valid assoc_id,
$user->roles()->attach(1, "outside contractor");
the insert works fine, and the first argument refers to the assoc_id in the table.
What is going wrong?

If you don't provie a key/keys for attach/sync, Eloquent will not insert anything. It's rather expected behaviour, since what you are trying to do is:
Create a link between X and null
this is not what ORM is supposed to do.
Instead insert those rows manually:
$data = [
'user_id' => 99,
'assoc_id' => null,
'role' => 'outside contractor'
];
DB::table('user_roles')->insert($data);

Related

Database(MySQL) Error

I am trying to insert two records to my database at the same time. One with the primary key and the other with the foreign key. However, I get the following error when I try implementing this:
Cannot add or update a child row: a foreign key constraint fails ....(database details).
I have used this query to create the foreign key:
ALTER TABLE `notes` ADD CONSTRAINT `notes_author_fk`
FOREIGN KEY (`authorid`) REFERENCES `audiofeed`.`author`(`authorid`) ON DELETE NO ACTION ON UPDATE CASCADE;
The error statement points at:
$query1 = "INSERT INTO notes(notename,categoryname,file,authorname)";
$query1 .= "VALUES ('$Trackname','$category','$name','$author')";
If the error does in fact occur during the insert statement that you posted, I notice that you are not inserting any value for the authorid column, which is the column that has a foreign key defined.
Normally, this should be ok, as it should simply insert NULL, and that would not violate the foreign key constraint.
However, if the authorid column in the notes table has a default value specification, it may be trying to insert an invalid default value that cannot be found in the author table, thus giving you the error.
You may want to verify how the authorid column is defined, and adjust it as necessary.
Or, make sure you set an appropriate value for authorid in your insert statement.

INSERT if exists UPDATE

I've been looking at other resources and am just getting a bit confused. I'd like to relate an example to my problem.
I have a game server which stores a unique id from steam in a database, and along with this has a column for specific permissions to that user. E.g id: 712309123810 permission: default
What I want to achieve is sending data from a form; $Id and $permission are posted. Insert this data into the database under columns for example sake; 'Id' and 'permission'. I can do this, what I am having issues is understanding how to UPDATE only the $permission column if the $id already exists in the db.
I have read about ON DUPLICATE KEY UPDATE , but am confused about how to correctly utilize it. I am fairly new to mysql.
Thanks for your time.
The on duplicate key fires when the insert part of the statement violates a unique constraint (in your case - the primary key on id). So, to put it all together:
INSERT INTO mytbale (id, permissions)
VALUES (:id, :permissions)
ON DUPLICATE KEY UPDATE permissions = :permissions
It's explained rather well by the manual:
http://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html
Your query might be something like:
INSERT INTO myTable (id, permissions) VALUES (712309123810, "default")
ON DUPLICATE KEY UPDATE permissions = "default";
This requires that the table contains a unique or primary key on the id column.
Normally, if you attempt to insert a new row that would create a duplicate value for a unique or primary key, it is an error. Using ON DUPLICATE KEY UPDATE changes that: instead, your insert transforms into an update.
The example query I gave will insert a new record if none with that id exists, or it will update the permissions of the existing one.
Typically, an id can have multiple permissions. If so, you don't want to overwrite the permissions; you want to accumulate them. If this is the case, you might need junction table to handle this:
create table UserPermissions (
UserPermissionsId int auto_increment primary key,
UserId int not null,
PermissionId int not null,
constraint fk_UserPermissions_UserId foreign key UserId references Users(UserId),
constraints fk_UserPermissions_PermissionId foreign key Permissions references Permissions (PermissionId)
);
If a user has only one permission that gets overwritten, then on duplicate key update is appropriate.

Deciphering & Fixing 'foreign key constraint fails' Error

I have this mysql query (which add values from a form into a table upon submission). It returns an error message:
$query = "INSERT INTO customers(customerNumber, customerName, contactLastName, contactFirstName, phone, addressLine1, addressLine2, city, state, postalCode, country, salesRepEmployeeNumber, creditLimit) VALUES ('$customer_number', '$customer_name', '$last_name', '$first_name', '$phone_number', '$address_1', '$address_2', '$city', '$state', '$postal_code', '$country', '$sales_number', '$credit_limit')";
$result = mysqli_query($dbc, $query)
or die(mysqli_error($dbc));
ERROR MESSAGE:
Cannot add or update a child row: a foreign key constraint fails (ikb2014_employees.customers, CONSTRAINT customers_ibfk_1 FOREIGN KEY (salesRepEmployeeNumber) REFERENCES employees (employeeNumber))
I am having a hard time deciphering where the 'foreign key constraint' fails. How can I change the the options in the database for the specific table to that I am able so run the query?
This is what the options in the phpMyAdmin show for the table employees and the column employeeNumber (assuming that is where the error is being caused).
# Name Type Collation Attributes Null Default Extra Action
1 employeeNumber int(11) No None AUTO_INCREMENT
I have not worked with a database before so it is hard for me to understand where and why the issue occurs. Any input on how to fix the constraint to properly run the query would be appreciated.
A failure of a foreign key constaint means that you are trying to enter data into a column of one table that does not exist in another table. The foreign key constraint is put in place to ensure that the data you insert into the child table exists in the parent table.
In your case, you're attempting to insert (or not attempting to insert) data in to the salesRepEmployeeNumber column of the customers table. In order to successfully do so, you need to ensure that the value that is provided for salesRepEmployeeNumber exists in the employeeNumber column of the employees table.
The foreign key constraint error is objecting to the value being assigned to the salesRepEmployeeNumber column. The foreign key constraint is checking that the value supplied for that column matches a row in employees table, it;s looking for a row that has the same value for employeeNumber, and it's not finding one.
If you don't want the database to enforce a foreign key constraint, then don't define one.
If you do want the constraint, then that's saying that you have to supply either a valid employeeNumber or a NULL value for salesRepEmployeeNumber.
From the code we're seeing, it looks like the SQL statement is vulnerable to SQL Injection. (We're not seeing any guarantees about the values of the variables being incorporated into the SQL text. If any of those values is potentially unsafe, then those values need to be properly escaped, for example, using mysqli_real_escape_string function.
A better pattern is to use a prepared statement with bind placeholders.
If your foreign key is wrong, you can easily remove it in phpMyAdmin.
Go to the customers table, click on 'structure' tab and at the bottom there will be an +Indexes hidden list, expand it and click DROP on the selected index.

In Relation View, why is it giving me an error, when I am trying to create a foreign key?

For my table, I have properly selected the indexes for some of my attributes that I want (4 foreign keys/indexes). Then when I click on Relation View, why is it when I click down to choose the right attribute ('edas'.'vehicle'.'owner') and choose a type for 'ON DELETE' and 'ON UPDATE' 2 out of 4 index/attributes are coming out with an error?
And it does not explain what type of error it is, it's simply just saying error. This is really confusing, can anyone help?
Below shows what one of the error's is coming out as:
Error
ALTER TABLE `vehicle`
ADD FOREIGN KEY ( `ownerID` )
REFERENCES `edas`.`vehicle` ( `modelID`)
ON DELETE RESTRICT
ON UPDATE RESTRICT;
One probable reason is that column types are different. If you want to add foreign keys, both columns must have the same type. The onliest difference is that ownerID can be NULL in any case while modelID can be NULL only if ownerID is NULL.

CakePHP delete not cascading. Causes foreign key error

I have a table called custom_carts and I have a table called custom_cart_items.
custom_cart_items has a foreign key called custom_cart_id that is set to custom_cart.id
According to the Cake Manual, when you call Model->delete() the first param is the id of the entry you want to delete and the second param is whether or not to cascade delete the dependent entries.
So when I call $this->CustomCart->delete(7,true) I get this error:
SQL Error: 1451: Cannot delete or
update a parent row: a foreign key
constraint fails
(`krake`.`custom_cart_items`,
CONSTRAINT `custom_cart_items_ibfk_1`
FOREIGN KEY (`custom_cart_id`)
REFERENCES `custom_carts` (`id`))
Here is the query:
DELETE `CustomCart`
FROM `custom_carts` AS `CustomCart`
LEFT JOIN `users` AS `User`
ON (`CustomCart`.`user_id` = `User`.`id`)
WHERE `CustomCart`.`id` = 25
Shouldn't it cascade and dlete the other entry too?
So why am I getting an error?
You must set the dependent parameter to true in the model with the hasmany relationship in order to enable cascading deletion.
Your model would look something like this:
class CustomCart extends AppModel {
var $name = 'CustomCart';
var $hasMany = array(
'CustomCartItem' => array(
'dependent'=> true
)
);
}
Please see http://book.cakephp.org/view/82/hasMany
Just adding fields to a table (regardless of the field name) does not tell CakePHP that they're associated, nor does it link them for cascading deletion.
You need to set the associations in your model: SEE DETAILS HERE.
On the other hand, if you want to delete a record from a table A, and there is another table B which as a FOREIGN KEY constraint on table A, you must set the option on that foreign key of the table B in the Database like this
"SET NULL ON DELETE".
I usually do this in MySqlWorkbench, but you can also use legacy SQL queries to create a table with such an option.