Doctrine cascade delete query? - mysql

I am using following query to delete countries in my database but it is giving foreign key error because countries has one to many relationship with cities.
I am using following query :
$cd = 1;
Doctrine_Core::getTable('country')->find($cd)->delete();
this query soft deletes if countries doesn't have any child but gives error if countries have any city.
I have also done following settings in country model:
$this->hasMany('city', array(
'local' => 'id',
'foreign' => 'country_id',
'cascade' => 'delete'
));
Please suggest.

In BaseCity.php you should have a relation to Country. In:
$this->hasOne('Country', array(
...
add this line:
"onDelete"=>"CASCADE"
When you delete country, cities will be deleted too. If you want to keep them, put
"onDelete"=>"SET NULL"

I think above way is also correct but I solved it in following way.
I made relation of country to city like this :
$this->hasMany('city', array(
'local' => 'id',
'foreign' => 'country_id',
'cascade' => array(
0 => 'delete',
)));
In YAML file I added like this :
cascade: [delete]
and it worked.

Related

Linq to Sql How To delete table along with all relationships

I have a table "User" With a relationship to around 7 other tables. If I try to delete the user it won't let me unless I delete all the data in the other tables that has a userId. Is there a way to delete everything automatically without having to delete each one of the tables with that UserId one table at a time?
You can use cascade delete.
Code first: In OnModelCreating method of context class:
modelBuilder.Entity<Table1>()
.HasOptional(c => c.User)
.WithMany(c => c.Table1s)
.HasForeignKey(c => c.UsereID).WillCascadeOnDelete(true);
modelBuilder.Entity<Table2>()
.HasRequired(c => c.User)
.WithMany(c => c.Table2s)
.HasForeignKey(c => c.UsereID).WillCascadeOnDelete(true);

Join DB tables with hasMany association - store in array

In a cakePHP application I am building, a profile can have multiple locations; the tables are called "profiles" and "locations" and in the model classes I have defined a HasMany relationship. Now I want the user to be able to search profiles based on their locations. After reading some questions here and the CakePHP Cookbook, I have decided I need to use SQL joins (in reality more tables are involved, and the result of a search should be based on conditions concerning different tables).
I have written the following function inside my Profile model:
public function findProfiles($long, $lat){
$options['joins'] = array(
array('table' => 'locations',
'alias' => 'Location',
'type' => 'Inner',
'conditions' => array('Location.profile_id = Profile.id'))
);
$options['order'] = array('Location.lng ASC'); //this is just as trial
return $this->find('all',$options);
}
The code works, but I get a copy of a profile for each location it possesses. That is, if a profile possesses 5 positions, I get five instances of that profile (each instance containing all five positions!)
How can I achieve this?
[edit]
eg. let's assume I only have one profile, with two positions. I get:
result[0][Profile]
[Position][0]
[1]
[1][Profile]
[Position][0]
[1]
Where the data in result[0] and result[1] is identical.
The problem happens because of the type of join used. With inner join you'll get this return with your query
profile_id location_id
---------------------------
1 2
1 3
And cake understands that as two records of Profile, so you get repeated Profiles with the same info.
If this were all the extent of your problem, I'd say "go with Containable behaviour and forget joins", but since you said there are more tables involved, maybe the type of join can't be changed. So to get the unique Profile without repetitions, you'll have to GROUP BY the query to get
profile_id location_id
---------------------------
1 2 & 3
with a code similar to this
$options['joins'] = array(
array('table' => 'locations',
'alias' => 'Location',
'type' => 'Inner',
'conditions' => array('Location.profile_id = Profile.id')),
'group' => 'Profile.id'
);
and you'll get rid of repetitions. For future problems like this, is best to first check the actual query that gets send to the DB, check yourself if the result that the DB gives you is what you want, and if not, see what you can do in cake to change it.

CakePHP HABTM Association not working

I've been trying to find an answer to my problem for hours. I am currently working with cakePHP 2.4.
I have two models, Users and Groups. I have created the following associations for each:
(User.php)
public $hasAndBelongsToMany = array(
'Group' =>
array(
'className' => 'Group',
'joinTable' => 'groups_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'group_id',
'unique' => true,
)
);
and (Group.php):
public $hasAndBelongsToMany = array(
'GroupUser' =>
array(
'className' => 'User',
'joinTable' => 'groups_users',
'foreignKey' => 'group_id',
'associationForeignKey' => 'user_id',
'unique' => true,
)
);
The reason I use GroupUser and not "User" is I get an error because I have already used "User for some other relation.
My form looks like this:
echo $this->Form->create('Group', array('controller' => 'group','action' => 'add'));
echo $this->Form->input('User.id', array('type' => 'hidden', 'value' => $authUser['id']);
echo $this->Form->input('Group.address');
echo $this->Form->end(__('Save', true));
I also have a table called groups_users with "id", "user_id" and "group_id"
When I submit the form, it created the new Group and saves the data, but the association is not created.
I tried manually filling a groups_users record with an existing user_id and group_id but still, when I use find(All), it doesn't find the expected association like it should according to the books.
I debugged the array that is being saved and it looks like this:
Array
(
[User] => Array
(
[user_id] => 39
)
[Group] => Array
(
[address] => asdasd, San Antonio, Texas 78233, EE. UU.
)
)
This is the code in my GroupsController add function:
if ($this->Group->save($this->request->data)) {
// redirect or do something
}
I have tried changing the array to work with saveAll like in the books, still only created new record but no association. And as I said, I mannually created a record and tried finding it and it wouldn't find it anyway.
I solved it apparently, I think it was because I hadn't created the GroupsUser.php model file. Not rreally sure because I changed a bunch of stuff! But maybe it helps someone.

CakePHP- querying a HABTM table and then accessing data

CAKEPHP question
I am querying my HABTM table successfully and returning the id of every student with the given group_id. This is my code for this.
$students = $this->GroupsStudents->find('list', array('conditions' => array('group_id' => $id)));
It works, no problem. I need to somehow use this info (namely the student's id), which is stored in $students, to query my students table and extract student's names based on their id.
If someone could give me some insight on this, that would be greatly appreciated.
if i'm understanding you right. as you can see from this if you have the id you can easily get the students name even though i'm not sure why you would do this and not just foreach the name.
foreach ($students as $id => $name) {
echo $students[$id]; // produces name
}
In Student model define relation with GroupStudent model as shown below:
var $hasMany = array(
'GroupStudent' => array(
'className' => 'GroupStudent',
'foreignKey' => 'student_id'
)
);
Then your write your query as
$students = $this->Student->find('all',
array(
'conditions' => array('GroupStudent.group_id' => $id)
'fields'=>array('Student.name','Student.id','GroupStudent.group_id'))
);
Note: Make sure your controller has $uses=>array('Student','GroupStudent'); defined!
and your are using plural names for model GroupStudents so correct them if possible

CakePHP 1.3 not saving to database but sql statement is correct and insertID is increased correctly

I already searched many forums for my really strange issue, but I still can't figure out whats going wrong during my save process... The issue: Cake says, my data was saved, creates an autoincrement-ID but no record is stored in the database.
The environment
I have a cake-1.3.13 app running for some time and now needed to add another database table, which is of course related to other tables. My problem is saving records for the habtm-relation table, which looks like this:
CREATE TABLE IF NOT EXISTS `employees_projects_rejectreasons` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`employees_project_id` int(10) unsigned NOT NULL,
`rejectreason_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `employees_project_id` (`employees_project_id`,`rejectreason_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=6;
I scaffolded the simple model only with basic validation criteria.
<?php
class EmployeesProjectsRejectreason extends AppModel {
var $name = 'EmployeesProjectsRejectreason';
var $validate = array(
'employees_project_id' => array(
'numeric' => array(
'rule' => array('numeric'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
'rejectreason_id' => array(
'numeric' => array(
'rule' => array('numeric'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $belongsTo = array(
'EmployeesProject' => array(
'className' => 'EmployeesProject',
'foreignKey' => 'employees_project_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Rejectreason' => array(
'className' => 'Rejectreason',
'foreignKey' => 'rejectreason_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
I created several records for Rejectreasons and EmployeesProjects, so I have some valid entries here in the database. Now I want to link them together by creating a new record in the given employees_projects_rejectreasons table. I try to do this from another controller (the EmployeesProjectsController). Here is my latest attempt to save the data:
$this->EmployeesProject->EmployeesProjectsRejectreason->create();
$eprData = array(
'EmployeesProjectsRejectreason' => array(
'employees_project_id' => (int)$id,
'rejectreason_id' => (int)$rrId
)
);
if($this->EmployeesProject->EmployeesProjectsRejectreason->save($eprData)) {
debug('successfully saved EPR with ID '.$this->EmployeesProject->EmployeesProjectsRejectreason->__insertID);
} else {
debug('could not save EPR with employees_project_id='.$id.' and rejectreason_id='.$rrId);
}
Now what happens
After I make an attempt to save a record, my debug gives me the following success report:
successfully saved EPR with ID 4
So the save() call returned true, a new ID was created by the auto_increment function of mySQL. So far so good. But when I check my database, there was no record created. But the auto_increment_counter was increased by 1, as if a record was stored, but it wasn't.
Running the app with debug-level 2, I can see the generated SQL-statement from cake, which looks perfectly fine to me:
INSERT INTO `employees_projects_rejectreasons` (`employees_project_id`, `rejectreason_id`) VALUES (3, 3)
If I run this statement directly on the sql server, the record ist inserted correctly.
What I already tried
I already tried different approaches with the save procedure. I tried working with setters instead of a data-array:
$this->EmployeesProject->EmployeesProjectsRejectreason->set('employees_project_id', $id);
as well, but it made no difference. After I wrote a custom save-method in the EmployeesProjectsRejectreason-Model, calling it from the controller, but it always produced the same result.
I tried
deleting the model-cache
restarting the server-instances and the server itself
Deleting the table and creating it again
disabling validation in the model
removing the unique foreign-key index
Saving with hard-coded and existing ids as foreign key
Some more strange behaviour
The last tests with hard-coded IDs in my controller code confronted me with more riddles: If I try storing existent foreign_key-IDs, the data is not saved as before. But if both IDs are hardcoded and NOT EXISTING (I used invented IDs 345 AND 567, which are definetely not existing in the database) a record was finally inserted!
Moreover I scaffolded Models, Views and Controllers for the new tables. When I run the scaffolded view "myApp/employees_projects_rejectreasons/add" and add a new record, everything works just fine.
I'm just not able to save the record from other controllers. Since I already have a huge headache, solving this problem, I highly appreciate any hint for a solution!!
Thanks in advance guys!
I finally found a solution to solve the issue. I still don't know, why the save code before did not work, but here is how I changed my code to make it work:
From my form, the data array comes in the following format:
Array
(
[EmployeesProject] => Array
(
[id] => 10
[user_id] => 0
[additional_information] => some comment text
[state] => absage
[Rejectreason] => Array
(
[0] => 1
[1] => 8
)
)
)
I searched for some solutions to save habtm relations in cakePHP directly with one call, but that does not seem to be possible in cake-1.3. So I created this pretty simple save routine in my EmployeesProjectController, which works perfectly fine for me:
if (!empty($this->data)) {
if ($this->EmployeesProject->save($this->data)) {
if(array_key_exists('Rejectreason', $this->data['EmployeesProject'])) {
foreach($this->data['EmployeesProject']['Rejectreason'] as $key => $rrId) {
$this->EmployeesProject->EmployeesProjectsRejectreason->create();
$this->EmployeesProject->EmployeesProjectsRejectreason->set('rejectreason_id', $rrId);
$this->EmployeesProject->EmployeesProjectsRejectreason->set('employees_project_id', $this->data['EmployeesProject']['id']);
if($this->EmployeesProject->EmployeesProjectsRejectreason->save()) {
}
}
}
}
}
Thanks #Yoggi for supporting me solving this issue!