CakePHP: Join Operation not working - php

I have Tables
Items, Attributes,Taxonomies, Taxonomy_attributes,Item_attributes.
Taxonomy_attributes have two fields attribute_id(which is a foreign key to id of attributes table) and taxonomy_id (which is a foreign key to id of taxonomies table).
On the other hand Item_attributes have two fields attribute_id(which is a foreign key to id attributes table) and item_id (which is a foreign key to of id items table).
Attributes table have following fields :- Name, Type and Checkable(which is either 0 or 1).
Items table have fields id and model.
Taxonomies table have fields if and name.
I want to add a method to Attribute model ,that returns list of all attributes with checkable equals 1 and join with items and taxonomies ,that return item model & taxonomy name for each attribute.
My code is as follows:-
public function getCheckables($checkable)
{
$data = $this->find('all',array(
'fields' => array('Attribute.name', 'Attribute.type', 'Item.model', 'Taxonomy.name'),
'conditions' => array('Attribute.checkable' => 1),
'joins' => array(
array(
'table' => 'item_attributes',
'alias' => 'ItemAttribute',
'type' => 'INNER',
'conditions' => 'ItemAttribute.Item_id = Item.id',
),
array(
'table' => 'items',
'alias' => 'Item',
'type' => 'INNER',
'conditions' => 'ItemAttribute.item_id = Item.id'
),
array(
'table' => 'taxonomy_attributes',
'alias' => 'TaxonomyAttribute',
'type' => 'INNER',
'conditions' => 'TaxonomyAttribute.Taxonomy_id = Taxonomy.id'
)
),
'recursive'=>-1
)
);
pr($data); die();
}
Can anybody guide me with the right code?

2 of your joins have the same condition : 'conditions' => 'ItemAttribute.Item_id = Item.id', in case of the first one, Item table was not yet joined and in case of the second one, because your first condition was wrong, the ItemAttribute table was not joined.

The actual Solution
public function getCheckables($checkable)
{
$data = $this->find('all',array(
'fields' => array('Attribute.name', 'Attribute.type', 'Item.model', 'Taxonomy.name'),
'conditions' => array('Attribute.checkable' => 1),
'joins' => array(
array(
'table' => 'item_attributes',
'alias' => 'ItemAttribute',
'type' => 'INNER',
'conditions' => 'ItemAttribute.attribute_id = Attribute.id',
),
array(
'table' => 'items',
'alias' => 'Item',
'type' => 'INNER',
'conditions' => 'ItemAttribute.item_id = Item.id'
),
array(
'table' => 'taxonomies',
'alias' => 'Taxonomy',
'type' => 'LEFT',
'conditions' => 'Item.category_id = Item.id'
)
),
'recursive'=>-1
)
);
pr($data); die();
}

Related

how to paginate in cakephp when result comes from several join conditions

I have a problem in cakephp pagination.Before i came deep i would like to display some code that i do in my controller
$this->paginate = array(
'joins' => array(
array(
'table' => 'job_posting_lists',
'conditions'=> array('job_posting_lists.firm_id')),
array(
'table' => 'firmsdetails',
'alias' => 'st',
'conditions'=> array('st.id')),
),
'conditions' =>array('job_posting_lists.select_industry'=>$id,'job_posting_lists.verify'=>1),
'fields' => array('job_posting_lists.*','st.*'),
'limit' => 3,
'contain' => array('job_posting_lists'));
$ListjobBycategories = $this->paginate();
echo "<pre>";print_r($ListjobBycategories); die;
$this->set('jobbycat',$ListjobBycategories);
the result come in ListjobBycategories correct but it returns more data about 1230 and in my job_posting_datas only 5 rows the next page return same result what i do
Try this code, make appropriate changes as per your code,
$this->paginate = array(
'joins' => array(
array(
'table' => 'tbl1',
'alias' => 'alias1',
'conditions'=> array('')
),array(
'table' => 'tbl2',
'alias' => 'alias2',
'conditions'=> array('')
),array(
'table' => 'tbl3',
'alias' => 'alias3',
'type' => 'left',
'conditions'=> array('')
),
),
'conditions' => $displayConditions, // Your query conditions
'fields' => $this->displayFields, // Your field set which you want to retrieve from tables
'limit' => $show_page,// number of records you wish to retrieve in each page
'group' => '', // field by which wish to grouping your data set
'contain' => array(''),//It will contain name of all the Models which are in Join
);
$ListjobBycategories = $this->paginate(); // Call pagination function, it will retrieve all records
Let me know if any query.

CakePHP JOIN not working

I am new in cakephp and I have searched a lot but couldn't get the solution. My query is not returning any error but it doesn't join the zone table with the disposeTemp table.
public function disposePreview(){
$this->loadModel('DisposeTemp');
$joins = array(
array(
'table' => 'zones',
'alias' => 'Zone',
'type' => 'inner',
'conditions' => array('DisposeTemp.zone = Zone.id')
)
);
$options = array(
'conditions' => array('DisposeTemp.is_delete' => 0,'DisposeTemp.status'=>2),
'order' => array('Item.item_category_id' => 'asc'),
'joins' => $joins
);
$getDT = $this->DisposeTemp->find('all', $options);
debug($getDT);
exit;
}
Set foreign key false , as you are not having proper naming convention for foreign key in DisposeTemp table , it was supposed to be zone_id to auto form relationship.
Now in your situation Use.
$joins = array(
array(
'table' => 'zones',
'alias' => 'Zone',
'type' => 'inner',
'foreignKey' => FALSE,
'conditions' => array('DisposeTemp.zone = Zone.id')
)
);

CakePHP Pagination with a model which has a HABTM model

I have 3 models (artist, media item, accent)
Artist hasMany media items,
Media items hasAndBelongsToMany accents,
Now what I am having issues with is how to search with pagination, I need to get pages of 8 artists and the media_items which match the accent entered. Hopefully that makes sense.
This is what I have currently
$this->Paginator->settings = array(
'limit' => 8,
'fields' => array("Artist.first_name",
"Artist.last_name", "Artist.image",
"Artist.image", "Artist.slug"),
'order' => "Artist.last_name",
'url' => $this->passedArgs,
'contain' => array(
'MediaItem'=> array(
"fields" => array("MediaItem.file",
"MediaItem.title",
"MediaItem.accent",)
),
'joins' => array(
array(
'table' => 'media_items',
'type' => 'INNER',
'alias' => 'MediaItem',
'conditions' => array(
"AND" => array('Artist.id = MediaItem.artist_id')
)
),
array(
'table' => 'media_accents_media_items',
'type' => 'RIGHT',
'alias' => 'MediaAccentsMediaItems',
'conditions' => array(
"AND" => array('MediaAccentsMediaItems.media_item_id = MediaItem.id')
)
),
array(
'table' => 'media_accents',
'type' => 'RIGHT',
'alias' => 'MediaAccent',
'conditions' => array(
"AND" => array('MediaAccent.id = MediaAccentsMediaItems.media_accent_id'),
"OR" => array('MediaAccent.name LIKE' => "%".$searchFor ."%")
)
)
),
'group' => 'Artist.id',
'update' => '.results-container',
'evalScripts' => true
);
it gets the right artists but returns all their tracks rather than the ones I need. Is there a better way rather than looping through the results pruning them? Which is my current backup plan.
Remove joins and just use Containable Behavior, here is docs for deeper associations.

Access related models/tables to inner join query in cakephp

I have this inner join query in a paginated model called Application
Application has many AssignedExploration
AssignedExploration belongs to Exploration
Exploration belongs to ExplorationCategory
ExplorationCategory belongs to Season
My query so far is:
$session_condition = array(
'table' => 'assigned_explorations',
'alias' => 'AssignedExploration',
'type' => 'INNER',
'conditions' => array(
'AssignedExploration.application_id = Application.id',
'OR' => array(
array('AssignedExploration.label' => $this->request->named['filter_session'])
)
)
);
I would like to add another query inside the OR that will get applications which has a Season.name = fall
I've tried adding array('Season.name' => 'fall') :
$session_condition = array(
'table' => 'assigned_explorations',
'alias' => 'AssignedExploration',
'type' => 'INNER',
'conditions' => array(
'AssignedExploration.application_id = Application.id',
'OR' => array(
array('AssignedExploration.label' => $this->request->named['filter_session']),
array('Season.name' => 'fall')
)
)
);
But no luck. Seems like Season is not recognized by AssignedExploration.
I would like to nest from AssignedExploration to Exploration to ExplorationCategory and to Season
And I don't have any idea on how to make it thru inner join query via cakephp.
Thanks in advanced.
EDIT: query as of now:
INNER JOIN
`ntc_development`.`assigned_explorations` AS `AssignedExploration` ON (
`AssignedExploration`.`application_id` = `Application`.`id`
AND
`AssignedExploration`.`label` = 'fall'
)
$this->paginate['Application'] = array(
'recursive' => -1,
'joins' => array(
array(
'table' => 'assigned_explorations',
'alias' => 'AssignedExploration',
'type' => 'inner',
'foreignKey' => true,
'conditions' => array('AssignedExploration.application_id = Application.id')
),
array(
'table' => 'seasons',
'alias' => 'Season',
'type' => 'inner',
'foreignKey' => true,
'conditions' => array('Season.id = Application.season_id') # whats your foregin key
),
),
'fields' => array(),
'conditions' => array('Season.name' => 'fail'),
);

cakephp find all join

$order = $this->Order->find('all', array(
'recursive' => 2,
'conditions' => array(
'Order.date' => $datefrom,
),
'joins' => array(
array(
'table' => 'purchase',
'alias' => 'Purchase',
'conditions'=> array(
'Purchase.pid = Order.pid',
)
),
array(
'table' => 'sales',
'alias' => 'Sales',
'conditions'=> array(
'Purchase.pid = Sales.pid',
)
),
),
));
Why does the above code doesn't select fields from purchase and sales, but only fields from order are returned. What is the necessary things to be added to make all data is returned. Thanks
Try this, I'm not sure if the 'type' and 'foreignKey' keys are required, but I typically include them when using the 'joins' key. Also I'm assuming the 'pid' is the correct foreign key.
$order = $this->Order->find('all', array(
'recursive' => -1,
'conditions' => array(
'Order.date' => $datefrom,
),
'joins' => array(
array(
'table' => 'purchase',
'alias' => 'Purchase',
'type' => 'INNER',
'foreignKey' => 'pid',
'conditions'=> array(
'Order.pid = Purchase.pid',
)
),
array(
'table' => 'sales',
'alias' => 'Sales',
'type' => 'INNER',
'foreignKey' => 'pid',
'conditions'=> array(
'Sales.pid = Purchase.pid',
)
),
),
));
If you already have relationships set up in the model, change the 'recursive' key to -1.
Just an idea,
'table' => 'purchase',
'alias' => 'Purchase',
isn't a typo, is it? Because I think, the usual name for the table according to cake-conventions would be 'purchases'... But I don't know your tables of course... ;)
First you need to create an association in Order Model file
Model:
public $hasMany = array(
'purchase' => array(
'className' => 'purchase',
'foreignKey' => 'pid',
'dependent' => true,
'counterQuery' => 'true'
),
'sales' => array(
'className' => 'sales',
'foreignKey' => 'pid',
'dependent' => true,
'counterQuery' => 'true'
),
);
Controller:
$order = $this->Order->find('all', array(
'recursive' => 2,
'conditions' => array(
'Order.date' => $datefrom,
)
);
Now you can get Order, Purchase and Sales related records.
Enjoy...
Controller::loadModel('User');
Controller::loadModel('Answer');
Controller::loadModel('Influence');
$users = $this->User->find('all', array('joins' => array(
array(
'table' => 'answers',
'alias' => 'Answer',
'type' => 'inner',
'foreignKey' => false,
'conditions' => array('Answer.user_id = User.id'),
),
array(
'table' => 'influences',
'alias' => 'Influence',
'type' => 'inner',
'foreignKey' => false,
'conditions' => array(
'Influence.user_id=Answer.user_id',
)
)
),'fields' => array(
'Answer.is_correct',
'Answer.answer',
'Answer.date as answered_date',
'Influence.signups',
'Influence.clicks',
'User.first_name',
'User.last_name',
'User.email',
'User.phone',
'User.flybuys' )
));
In order to get fields from other tables You should specify the fields you want.

Categories