CakePHP Joining same model twice - php

I have the following tables :
domains (id, name)
alignments (id, name, description)
alignments_domains(id, alignment_id, domain_id)
domains_domains(id, domain_id, authorized_domain_id)
All my foreign keys are made and what I'm trying to achieve is to have several authorized domains and several authorized alignments for each domain.
Thing is, when I cake bake model, controller and view I have this model :
class Domain extends AppModel
public $validate = array(
'name' => array(
'notEmpty' => array(
'rule' => array('notEmpty'),
//'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
),
),
);
public $hasAndBelongsToMany = array(
'Alignment' => array(
'className' => 'Alignment',
'joinTable' => 'alignments_domains',
'foreignKey' => 'domain_id',
'associationForeignKey' => 'alignment_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
),
'Domain' => array(
'className' => 'Domain',
'joinTable' => 'domains_domains',
'foreignKey' => 'domain_id',
'associationForeignKey' => 'domain_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
),
'Role' => array(
'className' => 'Role',
'joinTable' => 'roles_domains',
'foreignKey' => 'domain_id',
'associationForeignKey' => 'role_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
)
);
}
But when i try to insert a new domain, it give me this error :
Error: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`mythall_php`.`alignments_domains`, CONSTRAINT `alignments_domains_ibfk_2` FOREIGN KEY (`domain_id`) REFERENCES `domains` (`id`))
Do you have any suggestion on how I could make this possible ?
Thanks !

i am new to cakephp.
i experience this type of errors. my mistake is i have added more row before seting foreign key.
try to empty those four tables in phpmyadmin (check the relationship constrains once again)
add domain, alignment and do there.
and check this site for some reference :enter link description here

The solution I found was to change the hasandbelongtomany 'domain' to 'authorized_domain' and the associated foreign key to 'authorized_domain_id' and then baking was working properly.
'Authorized_Domain' => array(
'className' => 'Domain',
'joinTable' => 'domains_domains',
'foreignKey' => 'domain_id',
'associationForeignKey' => 'authorized_domain_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
)

Related

Cake PHP 2 Model association with finder query

I have a scenario where I have to associate the same model with hasMany.
My Table structure:
Has to Many relation for Children in PatientPaymentTransaction Model:
public $hasMany = [
'Children' => [
'className' => 'PatientPaymentTransaction',
'foreignKey' => false,
'dependent' => true,
// 'conditions' => ['Children.reference_id' => 'PatientPaymentTransaction.transaction_id' ],
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => 'SELECT *,children.reference_id as patient_payment_transaction_id FROM patient_payment_transactions children WHERE children.reference_id = {$__cakeID__$}',
'counterQuery' => ''
]
];
The response
The data is found but not appended in children.
What I am doing wrong?
Try to put it like this, inside the Model I am working my relationship $hasMany is laid out like this:
'PatientPaymentTransaction' => array(
'className' => 'PatientPaymentTransaction',
'foreignKey' => 'reference_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => 'SELECT *,children.reference_id from children FROM patient_payment_transactions children WHERE children.reference_id = {$__cakeID__$}',
'counterQuery' => ''
);

CakePHP HABTM condition

I want to make a condition on my HABTM attributes
I have the following HABTM relations in CakePHP 2.x:
Practise.php
public $hasAndBelongsToMany = array(
'Attribute' => array(
'className' => 'Attribute',
'joinTable' => 'practises_attributes',
'foreignKey' => 'practise_id',
'associationForeignKey' => 'attribute_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
)
);
Attribute.php
public $hasAndBelongsToMany = array(
'Practise' => array(
'className' => 'Practise',
'joinTable' => 'practises_attributes',
'foreignKey' => 'attribute_id',
'associationForeignKey' => 'practise_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
)
);
Now I want to find all including a condition on Attributes in my PractiseController.php
PractiseController.php
$cond['Attribute.id'] = array(1,2,3);
$this->Practise->find('all', array('conditions' => $cond));
Then I get the following error:
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Attribute.id' in 'where clause'
SQL Query:
SELECT
Practise.id,
Practise.title,
Practise.body,
FROM db.practises AS Practise
WHERE Attribute.id IN (1, 2, 3)
How can I make CakePHP also Join the HABTM table into the find query?
You can use contain for example
$this->Practise->find('all', array('contain' => 'Attribute.id = whatever'));
You can manually join too with:
$options['joins'] = array(
array('table' => 'practises_attributes',
'alias' => 'PractiseAttribute',
'type' => 'INNER',
'conditions' => array(
'Attribute.id = whatever',
)
) );

Cakephp Containable query with a condition AND model hasMany with also a condition

I'm here to ask a question related to the CakePhp engine.
I was just coding when I asked myself this :
I have a Customer model that hasMany Address BUT with 2 alias (one for Address.type = "l" and one for Address.type = "f")
Everything works fine, but let's suppose I want to make a special query that get me all the Customer data and the two related Address WITH a filter for each alias.
What should I do ?
Because when I'm making the query it's like the first condition (the one in the alias) is discard and the only one working is the last one.
Customer model
public $hasMany = array(
'AddressB' => array(
'className' => 'Address',
'foreignKey' => 'customer_id',
'dependent' => true,
'conditions' => array("AddressB.type" => "f"),
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
'AddressD' => array(
'className' => 'Address',
'foreignKey' => 'customer_id',
'dependent' => true,
'conditions' => array("AddressD.type" => "l"),
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
And then my query : (also in the Customer model)
$d = $this->find("all", array(
"conditions" => array(
"id" => $customer_id
),
"contain" => array(
"AddressD" => array(
"conditions" => array("active" => true),
"Cp"
),
"AddressB" => array(
"conditions" => array("active" => true),
"Cp"
)
)
)
);

Using Find to return values using a condition based on a related model

I have a Company model which is related to a MonthlyReturn model. A company can have many MonthlyReturns. I am trying to get an array of all companies which have a monthly return for a specified month.
The code I am using is as follows:
$this->Company->find('all', array('contain' => array(
'MonthlyReturn' => array(
'conditions' => array('MonthlyReturn.month' => "2012-01-01")
)
)));
The Company Model:
public $hasMany = array(
'Employee' => array(
'className' => 'Employee',
'foreignKey' => 'company_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
'MonthlyReturn' => array(
'className' => 'MonthlyReturn',
'foreignKey' => 'company_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
public $hasOne = 'Umuser';
}
This code is returning all companies rather than those with a return for the month. The 'MonthlyReturn.month' field will always be in the format above, i.e year and month will change but will always be the 1st of the month.
Any advice would be appreciated.
your code says, that you ask for a specific date, not a month.
try this:
$this->Company->find('all', array('contain' => array(
'MonthlyReturn' => array(
'conditions' => array('MonthlyReturn.month LIKE' => "2012-01%")
))));
I'm not sure if there is a better way but you can do it in two calls like this:
$company_ids = $this->MonthlyReturn->query("SELECT DISTINCT company_id FROM monthy_returns WHERE month = '2012-01-01';")
$this->Company->find('all', array(
'conditions' => array('Company.id' => $company_ids[0]),
'contain' => array('MonthlyReturn' => array(
'conditions' => array('MonthlyReturn.month' => "2012-01-01")
)
)));
That's the idea but some debugging may be required

Cakephp Multiple hasAndBelongsToMany HABTM

I have a table Tasks_Users with id, task_id,user_id and sender_id. Problem is user_id and sender_id are both referring to facebook_id in Users table and I'm not sure how I can hook them together with two foreign keys.
Is there a way we can get two foreign keys defined with HABTM relationship from one column?
UPDATE: Below is what I have currently set up in my Task model.
var $hasAndBelongsToMany = array(
'User' => array(
'className' => 'User',
'joinTable' => 'tasks_users',
'foreignKey' => 'task_id',
'associationForeignKey' => 'user_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
),
'Sender' => array(
'className' => 'User',
'joinTable' => 'tasks_users',
'foreignKey' => 'task_id',
'associationForeignKey' => 'sender_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
Below is for User model
var $hasAndBelongsToMany = array(
'Task' => array(
'className' => 'Task',
'joinTable' => 'tasks_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'task_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
Below is TasksUser model
var $belongsTo = array(
'Task' => array(
'className' => 'Task',
'foreignKey' => 'task_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Sender' => array(
'className' => 'User',
'foreignKey' => 'sender_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
I managed to get two multi-select boxes one for User_id and the other for Sender_id but the problem is I cannot save both at the same time for the same row...
The data arrays come as like this $this->data['User']['User'][] and $this->data['Sender']['Sender'][]
Theoretically it should save both but unfortunately it only saves Sender_id in the TasksUser table when you save using add action in scaffolding for Tasks controller and saves only User_id in the TasksUser table when you save using add action in scaffolding for Users controller.
The TasksUser tables are as below:
id task_id user_id sender_id
How can I make it so it saves both user_id and sender_id at the same row???
You have to put bellow code in your controller,
$this->TaskUser->bindModel(
array('belongsTo' => array(
'User1' => array(
'className' => 'User',
'foreignKey' => 'user_id'),
'User2' => array(
'className' => 'User',
'foreignKey' => 'sender_id'),
)
)
);
It should work normally, I mean without any other correction:
If you have a table User which relates via HABTM to other tables, when you make a saveAll CakePhp should automatically update the Join table. For me it does work.

Categories