SQL not inserting into table with relation in Yii - php

I'm trying to create a user and all the values are not inserting into the database. The systems_user table has a relation to a parties table as the party_id is the primary key of the sytems_user. Nothing is being inserted. Not even an error, it just goes back to the "create" page. Here is my schema:
--
-- Table structure for table `system_users`
--
CREATE TABLE IF NOT EXISTS `system_users` (
`party_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(200) NOT NULL,
`password` varchar(255) NOT NULL,
`date_last_login` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`status` varchar(50) NOT NULL DEFAULT 'Pending for Approval',
`date_created` datetime NOT NULL,
`date_modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`user_role` varchar(255) NOT NULL,
`isLogin` int(1) NOT NULL,
PRIMARY KEY (`party_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=221 ;
--
-- Constraints for table `system_users`
--
ALTER TABLE `system_users`
ADD CONSTRAINT `system_users_ibfk_1` FOREIGN KEY (`party_id`) REFERENCES `parties` (`id`);
-------------------------------------
-- Table structure for table `parties`
--
CREATE TABLE IF NOT EXISTS `parties` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`party_type_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `party_type_id` (`party_type_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=200 ;
--
-- Constraints for table `parties`
--
ALTER TABLE `parties`
ADD CONSTRAINT `parties_ibfk_1` FOREIGN KEY (`party_type_id`) REFERENCES `party_types` (`id`);
Where have I gone wrong? Why is it not inserting?
EDIT
Rules for SystemUser Model:
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('username, password, date_last_login, date_created, user_role, isLogin', 'required'),
array('isLogin', 'numerical', 'integerOnly'=>true),
array('username', 'length', 'max'=>200),
array('password, user_role', 'length', 'max'=>255),
array('status', 'length', 'max'=>50),
array('date_modified', 'safe'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('party_id, username, password, date_last_login, status, date_created, date_modified, user_role, isLogin', 'safe', 'on'=>'search'),
);
}
Rules for Parties:
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('party_type_id', 'required'),
array('party_type_id', 'length', 'max'=>10),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('id, party_type_id', 'safe', 'on'=>'search'),
);
}
EDIT Controller actionCreate()
A little background: as you can see from below, the conditions inside the if statement is only asking if the SystemUsers is set because the create come from the SystemUser form. My goal is to get the party_id of the system_user and insert it into the Parties table which is a different model from the SystemUsers that i'm using. So far when I run this, nothing happens.
public function actionCreate()
{
$parties = new Parties;
$model= new SystemUsers;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if (isset($_POST['SystemUsers']))
{
$parties->attributes = (HOW can I put the party_id from $model here?);
$model->attributes = $_POST['SystemUsers'];
$valid = true;
$valid &= $parties->validate();
$valid &= $model->validate();
if($valid)
{
$parties->id = $model->getPrimaryKey();
$parties->save(); /* First save parties. */
$model->save();
}
}
$this->render('create',array(
'model'=>$model,
'parties'=>$parties,
));

Yii doesn't insert not-safe values in database, I had this problem before, if you make all attributes safe, you will be fine. your attributes now are safe only in search scenario ( 'on'=>'search' ) . for making all attributes safe in all scenarios, remove 'on'=>'search' from both model rules.
You placed $parties->id = $customers->getPrimaryKey(); after $parties->save();.
if you want to save $parties->id too, place it before save()
Remove redirect line, I think your save() method cannot show errors because of that.
update :
What about this ?
if (isset($_POST['SystemUsers'])) {
$model->attributes = $_POST['SystemUsers'];
if($model->save()){ // save() does validation in itself
$parties->id = $model->getPrimaryKey();
$parties->save();
}
}

Related

Inserting Record into Database with CakePHP Results in Foreign Key Violation

I'm now to CakePHP (a few days) and I'm having issues with inserting records with Foreign Keys.
Basic idea, Warehouses.
I have a warehouses table that holds all the available warehouses and I have a warehouse_types table to hold the different types of warehouses. The warehouse_types table already has some data in it.
I have a simple add view (based off the blog example in CakePHP's Cookbook) and I have it displaying the names of the different types from the database.
When I save the page I get a Database error.
Error: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`kvs`.`warehouses`, CONSTRAINT `warehouses_ibfk_1` FOREIGN KEY (`warehouse_type_id`) REFERENCES `warehouse_types` (`id`))
The SQL that is being generated is:
SQL Query: INSERT INTO `kvs`.`warehouses` (`name`, `location`, `modified`, `created`) VALUES ('Name Text', 'Location Text', '2014-04-02 12:07:13', '2014-04-02 12:07:13')
If I output the information in the request->data object, it shows that it is getting a value for the warehouseType_id.
array(
'Warehouse' => array(
'name' => 'Name Text',
'location' => 'Location Text',
'warehouseType_id' => '1'
)
)
Any help on this would be awesome!
My database tables are as follows:
CREATE TABLE `warehouses` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`location` varchar(255) DEFAULT NULL,
`warehouse_type_id` int(10) unsigned NOT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `warehouse_type_id` (`warehouse_type_id`),
CONSTRAINT `warehouses_ibfk_1` FOREIGN KEY (`warehouse_type_id`) REFERENCES `warehouse_types` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1;
CREATE TABLE `warehouse_types` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
My models are as follows:
class Warehouse extends AppModel{
public $belongsTo = 'WarehouseType';
}
class WarehouseType extends AppModel{
}
My view (add.ctp) is as follows:
<h1>Add Warehouse</h1>
<?php
echo $this->Form->create('Warehouse');
echo $this->Form->input('name');
echo $this->Form->input('location');
echo $this->Form->input('warehouseType_id');
echo $this->Form->end('Create Warehouse');
?>
Finally, the add method in my WarehousesController:
public function add(){
//Check Request to see if it is a Post
if($this->request->is('post')){
$this->Warehouse->create(); //Make a new Warehouse object
debug($this->request->data);
if($this->Warehouse->save($this->request->data)){ //Try and save Warehouse
$this->Session->setFlash(__('Warehouse '.$this->request->data['Warehouse']['name'].' created'));
return $this->redirect(array('action' => 'index')); //Redirect back to Warehouse list
}
$this->Session->setFlash(__('Unable to add Warehouse :('));
}
$this->set('warehouseTypes', $this->Warehouse->WarehouseType->find('list'));
}
I've read over this answer here that seems the most relevant, but I'm lost: CakePHP Can't insert record with foreign key error
Also reviewed their documentation on saving: http://book.cakephp.org/2.0/en/models/saving-your-data.html#saving-related-model-data-hasone-hasmany-belongsto
Your column name is different than what is being used in CakePHP. Change CakePHP to use warehouse_type_id. (Your CakePHP code is using warehouseType_id)
Change this- on your view file-
Add Warehouse
<?php
echo $this->Form->create('Warehouse');
echo $this->Form->input('name');
echo $this->Form->input('location');
echo $this->Form->input('warehouseTypes');
echo $this->Form->end('Create Warehouse');
?>

Insert into Database not working due to Relations in Database

I've been trying to make an insert into the database whenever a user register, but I always got an SQL[23000] error and I realized that inside my database, there was a relationship to a different table and that is why I was getting an error. I'm used to creating a model and crud through Gii but this is the first time where I encountered an error because of relationships between tables. I think the problem is that I need to be able to insert into two models and I'm not completely sure how I should do that.
First things first, I'll show my schema:
CREATE TABLE IF NOT EXISTS `system_users` (
`party_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(200) NOT NULL,
`password` varchar(255) NOT NULL,
`date_last_login` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`status` varchar(50) NOT NULL DEFAULT 'Pending for Approval',
`date_created` datetime NOT NULL,
`date_modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`user_role` varchar(255) NOT NULL,
`isLogin` int(1) NOT NULL,
PRIMARY KEY (`party_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=219 ;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `system_users`
--
ALTER TABLE `system_users`
ADD CONSTRAINT `system_users_ibfk_1` FOREIGN KEY (`party_id`) REFERENCES `parties` (`id`);
---------------------------------------
CREATE TABLE IF NOT EXISTS `parties` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`party_type_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `party_type_id` (`party_type_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=200 ;
--
-- Constraints for dumped tables
--
--
-- Constraints for table `parties`
--
ALTER TABLE `parties`
ADD CONSTRAINT `parties_ibfk_1` FOREIGN KEY (`party_type_id`) REFERENCES `party_types` (`id`);
After this, I generated a model using Gii and I called it SystemUsers.php and I also generated the crud into the systemUsers under view.
Now problem is, every time I select "Create," it throws me an error that it cannot somehow find the parties id.
Just in case, here is the code of my model SystemUsers.php:
<?php
class SystemUsers extends CActiveRecord
{
/**
* Returns the static model of the specified AR class.
* #param string $className active record class name.
* #return SystemUsers the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* #return string the associated database table name
*/
public function tableName()
{
return 'system_users';
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('username, password, date_last_login, date_created, user_role, isLogin', 'required'),
array('isLogin', 'numerical', 'integerOnly'=>true),
array('username', 'length', 'max'=>200),
array('password, user_role', 'length', 'max'=>255),
array('status', 'length', 'max'=>50),
array('date_modified', 'safe'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('party_id, username, password, date_last_login, status, date_created, date_modified, user_role, isLogin', 'safe', 'on'=>'search'),
);
}
/**
* #return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'party_id' => array(self::BELONGS_TO, 'system_users', 'party_id'),
'party_id' => array(self::HAS_ONE, 'parties', 'id'),
);
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'party_id' => 'Party',
'username' => 'Username',
'password' => 'Password',
'date_last_login' => 'Date Last Login',
'status' => 'Status',
'date_created' => 'Date Created',
'date_modified' => 'Date Modified',
'user_role' => 'User Role',
'isLogin' => 'Is Login',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* #return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('party_id',$this->party_id,true);
$criteria->compare('username',$this->username,true);
$criteria->compare('password',$this->password,true);
$criteria->compare('date_last_login',$this->date_last_login,true);
$criteria->compare('status',$this->status,true);
$criteria->compare('date_created',$this->date_created,true);
$criteria->compare('date_modified',$this->date_modified,true);
$criteria->compare('user_role',$this->user_role,true);
$criteria->compare('isLogin',$this->isLogin);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
}
You have to implement a multi-step form and a single fatty controller which does all pluming working for you e.g adding/updating all three entities . please see this thread
as u have foreign key Constraints then you have have entry in parent table
system_users -> depends on parties
and
parties -> depends on party_types
so to insert the record in system_user you must have a record in Parites and similarly to insert the record in parties you must have a record in party_types
so first insert the record in party_type and for that party_type create record in Parties and then for that party_id create the record in system_user

How To Build Relations To Display Columns Of 4 Tables In Cgridview

I have a requirement where I need to build the relations between more than 3 tables.
I have 4 tables namely, Message, Flat, Person, Mapping tables.
Now, below tables have the following fields:
Message:
`Id` int(11) NOT NULL AUTO_INCREMENT,
`Mapid` int(11) DEFAULT NULL,
PRIMARY KEY (`Id`),
KEY `FK41715B218022FC0` (`MapId`)
Mapping
`Id` int(11) NOT NULL AUTO_INCREMENT,
`FlatId` int(11) DEFAULT NULL,
PRIMARY KEY (`Id`),
KEY `FKE2B3C68A24F94F50` (`FlatId`),
Flat
`Id` int(11) NOT NULL AUTO_INCREMENT,
`PersonId` int(11) DEFAULT NULL,
PRIMARY KEY (`Id`),
KEY `FK2FFF79122B94A6` (`PersonId`),
Person
`Id` int(11) NOT NULL AUTO_INCREMENT,
`Name` varchar(255) DEFAULT NULL,
`FlatId` int(11) DEFAULT NULL,
`Phone` varchar(255) DEFAULT NULL,
PRIMARY KEY (`Id`),
KEY `FKC4E39B55AF5432C` (`FlatId`),
Now, I have to build relations in such a way that in the Cgridview(admin.php) of Message, i should display PersonId of flat table and Name and Phone of Person table along with the columns of Message table.
I have defined relations like this in model class of message(message.php)
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'mapping' => array(self::BELONGS_TO, 'Mapping', 'MapId'),
'flat'=>array(self::HAS_ONE,'Flat',array('FlatId'=>'Id'),'through'=>'mapping'),
'person'=>array(self::HAS_ONE,'Person',array('PersonId'=>'Id'),'through'=>'flat'),
);
}
Can anyone explain me the step by step procedure to display the columns of person table in message gridview.
With assuming you can create dataProvider for the CGridView:
<?php
$this->widget('zii.widgets.grid.CGridView',array(
'id'=>'message-grid',
'dataProvider'=>$yourDataProvider //such as $model->search();
'filter'=>$model,
'columns'=>array(
'Id',
'Mapid',
'person.name',
'person.FlatId',
'person.Phone',
));
?>
You can pass a DataProvider to the view and use it in CgridView widget or use a 'search()' action from $model.
You can personalize the relation columns like this:
<?php
$this->widget('zii.widgets.grid.CGridView',array(
'id'=>'messagePerson-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'Id',
'Mapid',
array(
'header'=>'Person Name', // Personalize column name
'value'=>'$data->flat->person->Name',
'htmlOptions'=>array('style'=>'width:10%;'), // Personalize html attributes
),
'flat.person.FlatId', // Or directly with default relation name.
'flat.person.Phone',
));
?>

Yii framework Invalid datetime format on create

I have such projects table structure
CREATE TABLE IF NOT EXISTS `projects` (
`project_id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`description` text NOT NULL,
`url` varchar(255) NOT NULL,
`create_time` datetime DEFAULT NULL,
`create_user_id` int(11) DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`update_user_id` int(11) DEFAULT NULL,
PRIMARY KEY (`project_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
when I try to create new record with next form
Rules in model:
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('title, description, url', 'required'),
array('create_user_id, update_user_id', 'numerical', 'integerOnly'=>true),
array('title, url', 'length', 'max'=>255),
array('create_time, update_time', 'safe'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('project_id, title, description, url, create_time, create_user_id, update_time, update_user_id', 'safe', 'on'=>'search'),
);
}
I have received error
CDbCommand failed to execute the SQL statement: SQLSTATE[22007]:
Invalid datetime format: 1292 Incorrect datetime value: '' for column
'create_time' at row 1. The SQL statement executed was: INSERT INTO
projects (title, description, url, create_time,
create_user_id, update_time, update_user_id) VALUES (:yp0, :yp1,
:yp2, :yp3, :yp4, :yp5, :yp6)
Why? How can I tell Yii that datetime fields are not required and can contain default value if not entered.
Try this, and as this is self contained behavior inside Yii itself, it should work :
In the Rules model add this :
public function behaviors(){
return array('CTimestampBehavior'=>array(
'class' => 'zii.behaviors.CTimestampBehavior',
'createAttribute' => 'create_time',
'updateAttribute' => 'update_time',
'setUpdateOnCreate' => true,
));
}
U may try something like this after u click on the button Create it gets to some action
Take it for example actionCreate()
In actionCreate u do like as shown
public function actionCreate()
{
$model=new Project;
if(isset($_POST['Project']))
{
$model->attributes=$_POST['Project'];
$model->create_time=new CDbExpression('NOW()');
$model->save(false);
$this->redirect(array('view','id'=>$model->id));
}
$this->render('create',array(
'model'=>$model,
));
}
doesn't this work?
public function beforeSave()
{
if($this->isNewRecord)
{
$this->create_time=null;
$this->update_time=null;
}
return parent::beforeSave();
}

Yii on adding new record error : 1452 Cannot add or update a child row: a foreign key constraint fails

Adding new record it gives an error:
1452 Cannot add or update a child row: a foreign key constraint fails
public function relations()
{
return array(
'data' => array(self::HAS_ONE, 'Data', 'id'),
);
}
Here is my code for adding a new record:
public function actionAdd_Record()
{
$users = new Users();
$data = new Data();
if (isset($_POST['Users']) && isset($_POST['Data'])) {
if(!empty($_POST['Users_password'])) $_POST['Users']['password']=md5($_POST['Users_password']);
$users->created_date=date('Y-m-d H:i:s');
CActiveForm::validate(array($users, $data));
$users->attributes = $_POST['Users'];
$data->attributes = $_POST['Data'];
$valid=$users->validate();
$valid=$data->validate() && $valid;
if($valid){
$users->save();
$data->save();
$this->redirect(
array('view_record',
'id'=> $users->id)
);
}
}
$this->render(
'add_record', array(
'users'=> $users,
'data'=>$data
)
);
}
Here is the first table:
CREATE TABLE IF NOT EXISTS `data` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`investment_amount` float DEFAULT '0' COMMENT '投資額',
`withdrawals` float DEFAULT '0' COMMENT '引出額',
`investment_yield` float DEFAULT '0' COMMENT '運用利回り',
`account_balance` float DEFAULT '0' COMMENT '口座残高',
`status_account` enum('open','closed') DEFAULT 'open',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;
and the second table:
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(128) NOT NULL,
`password` varchar(128) NOT NULL,
`name` varchar(300) NOT NULL COMMENT '氏名',
`email` varchar(200) NOT NULL,
`user_type` enum('normal','admin') NOT NULL DEFAULT 'normal',
`created_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;
and it gives this error:
CDbCommand failed to execute the SQL statement: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (money_investment.data, CONSTRAINT FK_data_users FOREIGN KEY (id) REFERENCES users (id)). The SQL statement executed was: INSERT INTO data (investment_amount, withdrawals, investment_yield, account_balance, status_account) VALUES (:yp0, :yp1, :yp2, :yp3, :yp4)
This isn't a yii or PHP issue, but a database issue.
You're trying to insert a record that violates the relationships you've defined regarding primary keys. Things to check would be the relationships, as well as the field lengths.
It looks like you may still have a relationship defined on a column that doesn't exist (money_investment?)
Thank you for help, I fixed my problem.
I added $data->id=$users->id; because second table had no idea about the id. See here.
if($valid){
$users->save();
$data->id=$users->id;
$data->save();
$this->redirect(
array('view_record',
'id'=> $users->id)
);
}
foreign key constraints do not allow you to enter data in child before parents..
sometimes sql engines innoDb and MyIsam ..
read out its functionality u will come to know what sql engine would be preferred to use under foreign key constraint's coming issues....
you surly update your tables.
Best way is to See in Model
public function relations()
and compare these relations with your tables.
Any additional or wrong relation might create such problem.

Categories