How to set conditions for HABTM relation - php

In kid model i have defined this below HABTM relation.
public $hasAndBelongsToMany = array(
'Pics' => array(
'className' => 'Pic',
'joinTable' => 'pics_kids',
'foreignKey' => 'kid_id',
'associationForeignKey' => 'pic_id'
)
);
Pics table store details of pics like comment, pic_url and date and pics_kids table have pic_id and kid_id id's that relate pic and kids . If i have to retrieve record based on kid_id and date(date of pic in pics table) how to retrieve it?
$kid_pics=$this->kid->find('all', array(
'conditions' => array(
'kid.id' => 1,
'Pic.date' => '26/07/2014'
)
));
if i use above query i get error that no column Pic.date in where claue.

Add a condition to your HATBM relationship dynamically:
$this->Kid->hasAndBelongsToMany['Pic']['conditions'] = array(
'Pic.date' => '26/07/2014'
) ;
$kid_pics = $this->Kid->real(null, 1) ;

You can use built-in Containable Behavior
$this->Kid->Behaviors->load('Containable');
$kid_pics = $this->Kid->find('all', array(
'conditions' => array(
'Kid.id' => 1
),
'contain' => array(
'Pic' => array(
'conditions' => array(
'Pic.date' => '26/07/2014'
)
)
)
));

Related

CakePHP hasOne relationship with different table

Each Artikel has exactly one Barcode. For several reasons I want to split the Artikel model and the Barcode model. When I find() something from the artikel table it returns an array which contains the correct barcode section. But when I try to find a barcode, the array's artikel section is nulled.
This is what I mean:
// $this->Artikel->findById(102);
array(
'Artikel' => array(
'id' => '102',
'name' => 'Spätburgunder Spätlese Barrique',
'erzeuger_id' => '679',
'volumen_id' => '44',
'artikelgruppe_id' => '17'
),
'Barcode' => array(
'id' => '1',
'artikel_id' => '102',
'barcode' => '123456'
)
)
// $this->Barcode->findByBarcode(123456);
array(
'Barcode' => array(
'id' => '1',
'artikelnummer' => 'DE51076',
'barcode' => '123456'
),
'Artikel' => array(
'artikelnummer' => null, // this is null
'name' => null, // this is null as well
'erzeuger_id' => null, // also null
'volumen_id' => null, // ……
'artikelgruppe_id' => null // null
)
)
Any ideas what I did wrong?
These are the models
// Barcode.php
public $hasOne = array(
'Artikel' => array(
'className' => 'Artikel',
'foreignKey' => 'artikel_id'
)
);
// Artikel.php
public $hasOne = array(
'Barcode' => array(
'className' => 'Barcode',
'foreignKey' => 'artikel_id'
)
);
Article table - id, name, artikelgruppe_id and Barcode table - id, artikel_id, barcode
The correct way to relate these models is: Article hasOne Barcode and Barcode belongsTo Article
// Artikel.php
public $hasOne = array(
'Barcode' => array(
'className' => 'Barcode',
'foreignKey' => 'artikel_id'
)
);
// Barcode.php
public $belongsTo = array(
'Artikel' => array(
'className' => 'Artikel',
'foreignKey' => 'artikel_id'
)
);
Here article_id is in the Barcode table, so Article hasOne Barcode works as expected. Barcode hasOne Article would have worked if you had a barcode_id in your Article table.
But since you need the article from article_id field in Barcode table, you should use belongsTo relationship.
From what controller are you making those callings? If you are on the same model then is wrong because you must do the call through the references between the models. For example, I asume that you are in the Artikel model, so your first call is right, but the second one should be $this->Artikel->Barcode->findById(1)

inner join not working in cakephp

i have two tables in my database salaries model is Salary and userdetais model is Userdetail in which i want to fetch result bye comparing id and user_id code is
$this->Salary->find('all',
array(
'joins'=>array(
'table'=>'erp_userdetails',
'alias' => 'Userdetail',
'type' => 'INNER',
'conditions' => array('Salary.user_id' => 'userdetail.id')
)
)
);
Try this
this->Salary->find('all',
array('joins'=>
array(
array('table'=>'erp_userdetails',
'alias' => 'Userdetail',
'type' => 'INNER',
'conditions' => array('Salary.user_id' => 'userdetail.id')
)
)
)
);
You can use cakephp relational model.
Add belongsTo relation on Salary model
public $belongsTo=array(
"Userdetail"=>array(
"foreignKey"=>"user_id"
)
)

Display a field from a 3rd table

I am trying to display a field from a 3rd table in a relationship, and after checking posts here and the docs, I am still stuck.I have 3 models all related in some way. I have found similar posts here but I am still not getting it to work. I am learning so sorry if I have missed this somewhere in the docs but I have read a fair bit and have tried a lot. I am guessing too much now on this so I need help.
1)Tutorsession - belongsto teachers,
2) Teacher -has 1 user,hasmany tutorsessions
3) User- has 1 teacher, //////I want to display a field from this table given I display tutorsessions
In controller
$this->set('tutor',
$this->Tutorsession->find('first',
array(
'conditions' => array('Teacher.user_id' => $id),
'contain' => 'User.username'
)
)
); //////////no error but no results
from view echo '<td>'. $item['User']['username'].'</td>'; ///////error user undefined
The tutorsession automatically gets rows from teacher table but not user table witht he model setup on a findall.
I want to display a username from the user table. I display the tutorsession table , I then can display the teacher table with the model association but I cant go from the teacher table to the user table to get a user name from the user id as the common field. I have checked the docs below and I am not sure why my code isnt ble to display a username from users table.
http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html
update: here are the models
class User extends AppModel {
public $hasOne = array(
'Teacher' => array(
'className' => 'Teacher',
'dependent' => true
)
class Tutorsession extends AppModel
{
public $name='Tutorsession';
public $belongsTo = array(
'Teacher' => array(
'className' => 'Teacher',
'foreignKey' => 'teacher_id'
)
class Teacher extends AppModel
{
public $name='Teacher';
public $hasMany = array('Tutorsession');
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
)
);
Add containable behavior in your Model
public $actsAs = array('Containable');
Execute following query In controller
$contain = array('Teacher' => array('User'));
$this->set('tutor', $this->Tutorsession->find('first',array(
'conditions' => array('Teacher.user_id' => $id),
'contain' => $contain
)));
Try this:
$this->Tutorsession->recursive = 2;
$this->Tutorsession->Teacher->contain('User');
$this->set('tutor',
$this->Tutorsession->find('first',
array(
'conditions' => array('Teacher.user_id' => $id)
)
)
);
$tutor=$this->Teacher->find('first',
array(
'conditions' => array('Teacher.user_id' => $id)
)
);
debug($tutor); exit();
Your result similar:
'Teacher' => array(
'id' => '1',
'name' => 'abc',
'created' => '1397040385',
'updated' => '1397725860'
),
'User' => array(
'id' => '4',
'name' => 'administrators',
'created' => '1397032953',
'modified' => '1397032953'
),
'Tutorsession' => array(
0=>array(
'id' => '3',
'name'=>'abc',
'created' => '1400729137'
),
1=>array(
'id' => '4',
'name'=>'abc',
'created' => '1400729137'
)
)
Ensure your models are correct

Searching CakePHP HABTM relationship for results where 'all' terms match, not 'any'

In CakePHP 2.4, I'm trying to generate conditions for a search query that searches for data that has been tagged across a HABTM relationship.
My problem is twofold: I can't get my query to return only data tagged with ALL of my search terms, and I can't get my query to return results for partial tags.
This loop generates a working query returning data with ANY of the tags in the search query.
foreach($tags as $tag) {
$conditions['Tag.name'][] = $tag;
}
$query = $this->Tagged->getQuery('all', array(
'conditions' => $conditions,
'fields' => array('foreign_key'),
'contain' => array('Tag')
));
I'd like to get the loop to generate conditions returning only data tagged with ALL the search terms, not data tagged with any of them, and to return matches for partial terms.
EDIT 2:
My database schema looks like this (I'm using the CakeDC Tags plugin to add tags)
Posts
id | other_data
public $hasAndBelongsToMany = array(
'Tag' => array(
'with' => 'Tagged'));
Tagged
id | model | foreign_key | tag_id
Tags
id | name
This is the join I'm trying to use: It complains when I use Tag as an alias: Not unique table/alias: 'Tag'.
$joins = array(
array(
'table' => 'tags',
'alias' => 'queryTag',
'type' => 'LEFT',
'conditions' => array(
'queryTag.name' => 'keyword'
)
),
);
$query = $this->Tagged->getQuery('all', array(
//'conditions' => array('Tag.name LIKE' => '%' . $data['tags'] . '%'),
'joins' => $joins,
'fields' => array('foreign_key'),
'contain' => array('Tag')
));
return $query;
Its hard to tell without your full database schema but i think you need to join two tables like-
$options['joins'] = array(
array(
'table' => 'tagged_tags',
'alias' => 'TaggedTag',
'type' => 'LEFT',
'conditions' => array(
'TaggedTag.tagged_id' => 'Tagged.id'
)
),
array(
'table' => 'tags',
'alias' => 'Tag',
'type' => 'LEFT',
'conditions' => array(
'TaggedTag.tag_id' => 'Tag.id'
)
)
);

Join single item from related table based on min of field

I have an Item model which has the following associations:
public $hasOne = array(
'Project' => array(
'className' => 'Project',
'foreignKey' => 'item_id'
)
);
public $hasMany = array(
'ItemPic' => array(
'className' => 'ItemPic',
'foreignKey' => 'item_id',
'dependent' => false
)
);
I am wanting custom data for different views of Item. It seems like CakePHP automatically includes Project data (maybe because it is hasOne?) and does not include the ItemPic data. In the index I really don't even want the Project data... however, I do want the ItemPic data. For each Item record pulled, I want a single ItemPic record joined to it. This ItemPic should be basically ItemPic.item_id = Item.id and ORDER BY ItemPic.rank LIMIT 1.
The purpose of this is basically so that in the index I can show a list of Items and a picture associated with each item. I would like all of the images along with the Project data in the view for a single Item, but not in the list/index.
I was told I could use containable like this:
// In the model
public $actsAs = array('Containable');
// In the controller
$this->paginate = array(
'conditions' => $conditions,
'contain' => array(
'ItemPic' => array(
'fields' => array('file_name'),
'order' => 'rank',
'limit' => 1
)
)
);
The above actually works how I want... however, I was also told that doing this would cause an extra query to be ran for every single Item... which I feel I should avoid.
I tried doing this, but I get duplicate data and it doesn't attach any ItemPic data:
$this->paginate = array(
'conditions' => $conditions,
'joins' => array(
array(
'table' => 'item_pics',
'alias' => 'ItemPic',
'type' => 'LEFT',
'conditions' => array(
'ItemPic.item_id = Item.id'
),
'order' => 'rank ASC',
'limit' => 1
)
)
);
$paginated = $this->Paginator->paginate();
Can you please try this:
$this->paginate = array(
'conditions' => $conditions,
'joins' => array(
array(
'table' => 'item_pics',
'alias' => 'ItemPic',
'type' => 'LEFT',
'conditions' => array(
'ItemPic.item_id = Item.id'
),
'order' => 'rank ASC',
'limit' => 1
)
),
'fields' => array('Item.*','Project.*','ItemPic.*')
);
In the fileds section you may or may not assign "Item" , "Project" according to your requirment.
Thanks

Categories