yii migration return 1215 mysql error - php

After searching and checking my code over & over, now I want to ask.
I have 2 table umessage and ureply, when I want to add foreign key from ureply refrence to umessage I got 1215 mysql error.
Codes in file m140602_080318_create_table_umessage.php which create umessage table:
public function safeUp()
{
/*
* Create table umessage, this is connection way between customer & seller about specific object
* Add foreign key to table user and it's column id with sender column
* Add foreign key to table object and it's column id with objId column
*/
$this->createTable('tbl_umessage', array(
'id' => 'pk',
'time' => 'INT(15) NOT NULL',
'body' => 'TEXT NOT NULL',
'status' => 'TINYINT NOT NULL DEFAULT 0',
'visibleToS' => 'TINYINT NOT NULL DEFAULT 0',
'visibleToR' => 'TINYINT NOT NULL DEFAULT 0',
'sender' => 'INT(11)',
'objId' => 'INT(11) NOT NULL',
), 'ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci');
}
And codes in file m140602_080329_create_table_ureply.php which create ureply table:
public function safeUp()
{
/*
* Create table ureply which store all replies to exact message
* Add foreign key to table umessage and it's column id with msgId column
*/
$this->createTable('tbl_ureply', array(
'id' => 'pk',
'time' => 'INT(15) NOT NULL',
'body' => 'TEXT NOT NULL',
'isSender' => 'TINYINT NOT NULL DEFAULT 0',
'msgId' => 'INT(11) NOT NULL',
), 'ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci');
$this->addForeignKey('fk_ureply_umessage', 'tbl_ureply', 'msgId', 'umessage', 'id', 'CASCADE', 'CASCADE');
}
1215 error is for adding fk_ureply_umessage foreign key and I can't find my goofs.
Any help will be appreciated. thanks in advance.

You have a mistake in addForeignKey method:
$this->addForeignKey('fk_ureply_umessage', 'tbl_ureply', 'msgId', 'umessage', 'id', 'CASCADE', 'CASCADE');
the table that the foreign key references to should be tbl_umessage not umessage:
$this->addForeignKey('fk_ureply_umessage', 'tbl_ureply', 'msgId', 'tbl_umessage', 'id', 'CASCADE', 'CASCADE');

The error is related to foreign key references check the data type is equivalent between the foreign key and its reference

Related

Laravel inserting parent child fails inside transaction

I am trying to perform 2 inserts, in 2 tables table are constrained via a foreign key. These 2 operations MUST be performed inside a transaction to prevent eventual failures. (In reality I need to perform more inserts on more tables so transactions are important; but the 2 tables in this example are enough to replicate the problem)
The database driver is pgsql
SomeRepo.php (Tried it with the the transaction closure variant as well)
DB::beginTransaction();
try {
$parentData = [
'name' => 'Parent name'
];
$parent = new Parent($parentData);
$parent->save();
$childData = [
// Tried it with and without setting "parent_id" here
'parent_id' => $parent->id,
'name' => 'Child name'
];
$child = new Child($childData);
$parent->children()->save($child);
DB::commit();
} catch (Exception $e) {
DB::rollback();
}
Parent.php
protected $fillable = [
'name'
];
public function children()
{
return $this->hasMany(Child::class);
}
Child.php
protected $fillable = [
'name', 'parent_id'
];
Execution fails when trying to insert the child row, with the return parent id.
insert or update on table "child" violates foreign key constraint "child_parent_id_foreign"
EDIT
Child table SQL:
DROP TABLE IF EXISTS "public"."child";
CREATE TABLE "public"."child" (
"id" int4 NOT NULL DEFAULT nextval('child_id_seq'::regclass),
"parent_id" int4 NOT NULL,
"is_read" bool NOT NULL DEFAULT false,
"created_at" timestamp(0) DEFAULT now(),
"updated_at" timestamp(0),
"deleted_at" timestamp(0)
)
;
ALTER TABLE "public"."child" OWNER TO "my_user";
-- ----------------------------
-- Primary Key structure for table child
-- ----------------------------
ALTER TABLE "public"."child" ADD CONSTRAINT "child_pkey" PRIMARY KEY ("id");
-- ----------------------------
-- Foreign Keys structure for table child
-- ----------------------------
ALTER TABLE "public"."child" ADD CONSTRAINT "child_parent_id_fkey" FOREIGN KEY ("parent_id") REFERENCES "public"."parent" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION DEFERRABLE INITIALLY DEFERRED;
To save data in related table use this
Parent::create(['name'=>'parent name']); //save in parent table
$lastId = Parent::query()->max('id'); //get last inserted row id
$parent = App\Parent::find($lastId);
$child = $parent->children()->create([
'message' => 'A new comment.',
]);
You can also use createMany method
$parent = App\Parent::find($lastId);
$parent->children()->createMany([
[
'message' => 'A new comment.',
],
[
'message' => 'Another new comment.',
],
]);
Try it with this code by using create and createMany on the relation of the Parent model:
// Create the parent object.
$parent = Parent::create([
'name' => 'Parent 1'
]);
// Insert one.
$child = $parent->children()->create([
'name' => 'Child 1',
]);
// Insert many.
$parent->children()->createMany([
[
'name' => 'Child 2',
],
[
'name' => 'Child 3',
],
]);
You can try this one
try {
DB::beginTransaction();
$parent = Parent::create([
'name' => 'Parent name'
]);
$parent->children()->create([
'parent_id' => $parent->id,
'name' => 'Child name'
]);
DB::commit();
} catch (Exception $e) {
DB::rollback();
}
alter the foreign key-- run this sql on the database
alter table child drop constraint child_parent_id;
alter table child add foreign key (parent_id) references parent(id) deferrable initially deferred;
This will allow you to create the child or parent in either order and the constraint will not be validated until the commit. It should not be necessary in this case-- however, It does depend on how your IDs are generated.
children function needs a middle table change it to :
public function children()
{
return $this->belongsToMany(Child::class);
}
and don't do this $parent->children()->save($child);.
or if you want to go that way make child_parent table, with 2 fields child_id and parent_id.

Laravel inserting by relationship to composite key table

I have these tables currently:
User table
id (primary key), name, email
User Model
protected $fillable = ['name', 'email'];
protected $visible = ['id','name','email'];
//Relationship
public function customAttributes()
{
return $this->hasMany('App\Models\UserAttribute');
}
UserAttribute Table
user_id, attribute_id, value //user_id and attribute_id is a composite key, both foreignkeys acting as primary keys establishing an unique combination
UserAttribute Model
protected $fillable = ['user_id', 'attribute_id','value'];
protected $visible = ['user_id', 'attribute_id','value'];
I'll use the following example to explain the issue:
$user = $this->user->create(['name' => 'admin', 'email' => 'admin#admin.com']);
//This works
$user->customAttributes()->save(new \App\Models\UserAttribute(['user_id' => $user->id, 'attribute_id' => 1, 'value' => 'Just a custom1']));
//This does not work
$user->customAttributes()->create([new \App\Models\UserAttribute(['user_id' => $user->id, 'attribute_id' => 1, 'value' => 'Just a custom1'])]);
I could just repeat the save for every custom that I want since it works, but I'm trying to figure out why create doesn't work.
The error I'm getting when I use create is (and yes, I've checked the record exists in the table that isn't listed here):
Cannot add or update a child row: a foreign key constraint fails (`testdatabase`.`user_attributes`,
CONSTRAINT `user_attributes_attribute_id_foreign` FOREIGN KEY (`attribute_id`) REFERENCES `attributes` (`id`))
This is the query it's trying to execute:
insert into `user_attributes` (`user_id`) values (1)
I'm just curious at why this doesn't work with create, I'm not sure if it's something related to this specific scenario (create to a composite key table by relationship). It's somewhat ignoring the value and attribute_id field in the query that is executing
try this:
$user->customAttributes()->create(['user_id' => $user->id, 'attribute_id' => 1, 'value' => 'Just a custom1']);
customAttributes() already returns you instance of UserAttribute model, you don't need to enject that dependency when you use create() method via that relation
your query should be like below;
$user->customAttributes()->insert([
[
'user_id' => $user->id,
'attribute_id' => 1,
'value' => 'Just a custom1'
],
[
'user_id' => $user->id,
'attribute_id' => 2,
'value' => 'Just a custom2'
],
]);

CODEIGNITER how to insert user_ID to mySQL when that user_ID is logged in

this is the error page
Cannot add or update a child row: a foreign key constraint fails (latihan_ci.adventure, CONSTRAINT adventure_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (user_id) ON UPDATE CASCADE)
INSERT INTO adventure (name, category, place, state) VALUES ('semeru', 'gunung', 'asa', 'asd')
and this is my controller
public function addTrip(){
$this->load->model('userModel');
$newTrip = ['name' => $this->input->post('name'),
'category' => $this->input->post('category'),
'place' => $this->input->post('place'),
'state' => $this->input->post('state'),
];
$data['users'] = $this->userModel->getUserId()->result();
$this->db->insert('adventure',$newTrip);
$this->db->insert('adventure',$data);
redirect('userController/profile');
}
and this is my Model
public function getUserId()
{
return $this->db->get('users',['user_id']);
}
so how to add the user_ID to the mySQL when the value is user_ID that is already login..Thanks alot
when you are login at that time user_id store in session after use
controller
$newTrip = ['name' => $this->input->post('name'),
'category' => $this->input->post('category'),
'place' => $this->input->post('place'),
'state' => $this->input->post('state'),
'user_id'=>$this->session->userdata('userdata'),
];

Add foreign key in Yii migrations

I try to add foreign key to table, but when I run migration I getting this error:
General error: 1005 Can't create table 'chooseone.#sql-49a_49'
Its strange because chooseone is the name of my database. Here is how I try to add FK:
$this->addForeignKey('FK_user_profile', 'tbl_profile', 'user_id', 'tbl_user', 'id', 'CASCADE', 'CASCADE');
So what I am doing wrong?
I solve this issue. I change my definition of id column in tbl_user:
'id' => 'INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY',
to
'id' => 'pk',
and all works properly.

CakePHP linking a hasMany relationship with a different index

I have a table of securities like so:
CREATE TABLE IF NOT EXISTS `securities` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ticker` varchar(36) NOT NULL,
`name` varchar(180) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ticker` (`ticker`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=585 ;
I.e. the primary key is id whilst there is another unique index ticker.
The ticker index refers to my other table, secuity_prices which has this
CREATE TABLE IF NOT EXISTS `security_prices` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`price_date` date NOT NULL,
`ticker` varchar(36) NOT NULL,
`price` decimal(10,6) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=88340 ;
I want to define a hasMany relationship between them such that security hasMany securityPrice [securityPrice belongsTo security].
The problem I am having is that Cake is using the primary key of security to link to the security_prices table instead of the ticker field. How can I get the join to be made via the ticker?
Here are my relationships:
//Security
public $hasMany = array(
'SecurityPrice' => array(
'className' => 'SecurityPrice',
'foreignKey' => 'ticker',
)
);
//SecurityPrice
public $belongsTo = array(
'Security' =>
array(
'className' => 'Security',
'foreignKey' => 'ticker',
)
);
You can't use $hasMany to do this, because those associations require that you follow Cake's naming conventions for the primary key. You are trying to join two tables via non-primary key columns. That can be done, but not via Cake's automatic associations.
You need to add the join conditions when performing a find operation or pagination operation.
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#joining-tables
$options['joins'] = array(
array('table' => 'security_prices',
'alias' => 'SecurityPrice',
'type' => 'LEFT',
'conditions' => array(
'Security.ticker = SecurityPrice.ticker',
)
)
);
$Security->find('all', $options);
If you have to do this often, then you should create a custom find type.
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#creating-custom-find-types
class Security extends AppModel {
public $findMethods = array('ticker' => true);
protected function _findTicker($state, $query, $results = array()) {
if ($state === 'before') {
$query['joins'][] = array(
array('table' => 'security_prices',
'alias' => 'SecurityPrice',
'type' => 'LEFT',
'conditions' => array(
'Security.ticker = SecurityPrice.ticker',
)
)
);
return $query;
}
return $results;
}
}
Then later it's easy to find with the join.
$Security->find('ticker',.....);

Categories