Chained contain and paginate in Cakephp - php

Two Languages belongs to Lset, Lset HABTM Translator
It is defined as follows:
Translator:
var $hasAndBelongsToMany = array(
'Lset' => array(
'className' => 'Lset',
'joinTable' => 'lsets_translators',
'foreignKey' => 'translator_id',
'associationForeignKey' => 'lset_id',
)
);
Lset:
var $belongsTo = array(
'langfrom' => array(
'className' => 'Language',
'foreignKey' => 'from_id',
),
'langto' => array(
'className' => 'Language',
'foreignKey' => 'to_id',
)
);
The thing i am doing is :
$this->paginate['Translator']['contain'] = array('Lset' =>array('langfrom', 'langto'));
debug($this->paginate());
In my opinion I should get Translator with Lsets, each of them with associated Language, but i only get an error:
SQL Error: 1054: Unknown column 'Lset.langfrom' in 'field list'
How should I do this ?

okay, found that. assosciants should be named with capital letter.

Related

CakePHP - saving HABTM fails

I have tables that looks like this. Basically WarehousePlace can have many ItemType in it and ItemType can be used by many WarehousePlace. But when I try to save I get an database error:
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'WarehousePlacesItemType.item_type_id' in 'field list'
SQL Query: SELECT `WarehousePlacesItemType`.`item_type_id` FROM `modules`.`warehouse_places_item_types` AS `WarehousePlacesItemType` WHERE `WarehousePlacesItemType`.`warehouse_place_id` = '22'
But everything is done by conventions and also debugged data is like it should be and I do not see what is wrong.
WarehousesController
public function add() {
$this->load();
if ($this->request->is('post')) {
$data = array(
'WarehousePlace' => array(
'name' => $this->request->data['WarehousePlace']['name'],
),
'ItemType' => array(
'ItemType' => $this->request->data['ItemType']['ItemType']
)
);
$this->WarehousePlace->create();
if ($this->WarehousePlace->saveAll($data, array('validate' => 'first', 'deep' => true))) {
//success
}
if ($this->WarehousePlace->validationErrors) {
//validation
} else {
//error
}
}
}
tables:
warehouse_places_item_types(warehouse_places_id,item_types_id) -> no primary key since CakePHP 2,
warehouse_places(id, name),
item_types(id, name)
Models:
ItemType
public $hasAndBelongsToMany = array(
'WarehousePlace' => array(
'className' => 'WarehousePlace',
'joinTable' => 'warehouse_places_item_types',
'foreignKey' => 'item_type_id',
'associationForeignKey' => 'warehouse_place_id',
'unique' => 'keepExisting',
)
);
WarehousePlace
public $hasAndBelongsToMany = array(
'ItemType' => array(
'className' => 'ItemType',
'joinTable' => 'warehouse_places_item_types',
'foreignKey' => 'warehouse_place_id',
'associationForeignKey' => 'item_type_id',
'unique' => 'keepExisting',
)
);

hasAndBelongsToMany in CakePHP 2.x

I need help for the simple relationchip in cakephp 2.x, I believe this right however not working:
Customer.php (Model)
public $hasAndBelongsToMany = array(
'Note' => array(
'className' => 'Note',
'joinTable' => 'customers_notes',
'foreignKey' => 'customer_id',
'associationForeignKey' => 'note_id',
'unique' =>false,
'dependent'=>true,
)
);
Note.php (Model)
public $hasAndBelongsToMany = array(
'Customer' => array(
'className' => 'Customer',
'joinTable' => 'customers_notes',
'foreignKey' => 'note_id',
'associationForeignKey' => 'customer_id',
'unique' =>false,
'dependent'=>true
)
);
CustumersController.php (Controller I make the find)
public function admin_notes($id=null){
$this->layout="Adm.admin";
$all = $this->Customer->Note->find('all', array(
'limit' => 10,
'conditions' => array(
"CustomersNote.customer_id" => $id
),
'order'=>'CustomersNote.id DESC'
));
$this->set('notes', $all);
}
The error
SQL Query: SELECT `Note`.`id`, `Note`.`titulo`, `Note`.`conteudo`, `Note`.`created`, `Note`.`modified`, `Note`.`user_id` FROM `crm_prado`.`notes` AS `Note` WHERE `CustomersNote`.`customer_id` = '1' LIMIT 10
Thanks!
The soluction is really simple.
In find uses
$all = $this->Customer->find('all', array(
'recursive'=>2,
'conditions'=>array(
'Customer.id'=>$id
)
));
Works!, but now the recursive mode don't work...

cakephp - using loadmodel and getting data related to the loaded model

In a controller which is completely unrelated - a DoctorsController, I need to get some info from my ChildrenMedicine model and also the name of the medicine which is in it's own related Medicine model. So in my (unrelated) DoctorsController controller I use:
$this->loadModel('ChildrenMedicine');
$this->ChildrenMedicine->recursive = 2;
$childsMeds = $this->ChildrenMedicine->find('all', array('conditions'=>array('child_id'=>$child)));
I expected this to get me an array with all the medicines which the child currently uses, plus the info from the medicines table so I can get the name. However it only gives me:
$childsMeds[0]['ChildrenMedicine']
$childsMeds[1]['ChildrenMedicine']
whereas I was hoping for
$childsMeds[0]['ChildrenMedicine']
$childsMeds[0]['Medicine']
$childsMeds[0]['Child']
$childsMeds[1]['ChildrenMedicine']
$childsMeds[1]['Medicine']
$childsMeds[1]['Child']
Can anyone enlighten me?
EDIT - my ChildrenMedicine model associations:
public $belongsTo = array(
'Child' => array(
'className' => 'Child',
'foreignKey' => 'child_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Medicine' => array(
'className' => 'Medicine',
'foreignKey' => 'medicine_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
Use Containable Behavior.
$this->loadModel('ChildrenMedicine');
$this->ChildrenMedicine->Behaviors->load('Containable');
$childsMeds = $this->ChildrenMedicine->find('all',
array(
'conditions' => array('child_id'=>$child),
'contain' => array('Child', 'Medicine')
));
A alternative method would be to use joins to solve this issue. It would be a better option that relying on setting recursive = 2.
$data = $this->ChildrenMedicine->find('all', array('conditions' => array('child_id'=>$child), 'joins' => array(
array(
'table' => 'medicines',
'alias' => 'Medicine',
'type' => 'inner', // could also do outter
'foreignKey' => false,
'conditions'=> array('ChildrenMedicine.medicine_id= Medicine.medicine_id')
))));
You can read more on joins here
For setting up HABTM relationships this article seems helpful. Look at "The Model" code

problem with counterCache of cakePHP

I have in a video sharing website project these models :
class Video extends AppModel {
var $name = 'Video';
var $hasAndBelongsToMany = array(
'Tag' => array(
'className' => 'Tag',
'joinTable' => 'videos_tags',
'foreignKey' => 'video_id',
'associationForeignKey' => 'tag_id',
'unique' => true,
)
);
}
class Tag extends AppModel {
var $name = 'Tag';
var $hasAndBelongsToMany = array(
'Video' => array(
'className' => 'Video',
'joinTable' => 'videos_tags',
'foreignKey' => 'tag_id',
'associationForeignKey' => 'video_id',
'unique' => true,
)
);
}
class VideosTag extends AppModel {
var $name = 'VideosTag';
var $belongsTo = array(
'Video' => array(
'className' => 'Video',
'foreignKey' => 'video_id',
),
'Tag' => array(
'className' => 'Tag',
'foreignKey' => 'tag_id',
'conditions' => '',
'counterCache' => 'videos_tag_counter'
)
);
}
The counterCache for tags is not working. I don't know why and when I tried to add a beforeSave() callback to videosTag model I found that it doesn't execute when a video get saved (and this video has tags and i find them in the database so how the relation videosTags is saved ? ) !!! can any body explain why this is happening.
Saving a Video with data like this:
array(
'Video' => array(
...
),
'Tag' => array(
'Tag' => array(
...
),
),
);
on the Video model will not trigger a beforeSave callback on the VideosTag model because Cake handles HABTM data without requiring (or even using) the join/with/through model.
There is no built in functionality for what you are trying to achieve, as far as I am aware.
Check out Counter Cache behavior for HABTM relations, might do what you need

How do I create a Unary association in CakePhp?

Is there a shortcut for creating Unary associations in Cake?
For example, a user is a friend of another user. I'm pretty sure it's going to violate cake's conventions if I try it the hard way and code the associations myself.
Cake has HABTM:
var $hasAndBelongsToMany = array(
'User' =>
array(
'className' => 'User',
'joinTable' => 'friends',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id',
'unique' => true
)
);
Will this work? A user model assoc to another user model.
Update:
How do I save the data now?
$this->data["Friend"] = $request["Requester"];
$this->data["Admirer"] = $request["Requestee"];
$this->Friend->create();
$this->Friend->save($this->data);
$request["Requester"] and $request["Requestee"] both hold objects of type User.
The HABTM rel is defined in the User model
var $hasAndBelongsToMany = array(
'Friend' => array(
'className' => 'Friend',
'joinTable' => 'friends',
'foreignKey' => 'user_id',
'associationForeignKey' => 'id'
),
'Admirer'=>array(
'className'=>'Friend',
'joinTable'=>'friends',
'foreignKey' => 'friend_id',
'associationForeignKey' => 'id',
)
);
All that happens is the $data->["Friend"]'s id is stored in the id column of the friends table
Here is a solution I use in an example application
Two tables are needed, users and followers. The important fields are User->id, Follower->user_id, Follower->friend_id.
I hope this snippet helps.
&lt?php
class User extends AppModel {
public $useTable='users';
public $hasAndBelongsToMany=array(
'Friend'=>array(
'className'=>'User',
'joinTable'=>'followers',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id',
),
'Admirer'=>array(
'className'=>'User',
'joinTable'=>'followers',
'associationForeignKey' => 'friend_id',
'foreignKey' => 'user_id',
),
);
}
-teh
Bjorn,
he is asking about User habtm User...
your join table should be users_users and the relation should look like this
var $hasAndBelongsToMany = array(
'Friend' =>
array(
'className' => 'UserUser',
'joinTable' => 'users_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'friend_id',
'unique' => true
)
);
i think that should do the trick
In CakePHP there are several variables in your model available to do that, like $hasMany, $belongsTo and $hasAndBelongsToMany. Please read the Cookbook for further explaination.. http://book.cakephp.org/view/78/Associations-Linking-Models-Together .
In your example, I think you need HABTM.

Categories