CakePHP Multidimensional Model - Joining in wrong place - php

I'm having an issue with Cake joining tables in the wrong place :(
I have three tables - CC_PLAYLIST, CC_PLAYLISTCONTENTS, and CC_FILES.
I'd like to get a list of all playlists, with all of their contents, and then the relevant file information for each piece of playlist content.
I.E
Playlist 1
-- Playlist Content 1
---- File Info
-- Playlist Content 2
---- File Info
-- Playlist Content 3
---- File Info
Playlist 2
-- Playlist Content 123
---- File Info
In my Model (AirtimePlaylist) I get this data with
$result = $this->find('all', array(
'contain' => array(
'AirtimePlaylistContent' => array(
'fields' => array('AirtimePlaylistContent.id', 'AirtimePlaylistContent.playlist_id', 'AirtimePlaylistContent.file_id'),
'AirtimeFile' => array(
'fields' => array('AirtimeFile.id', 'AirtimeFile.track_title', 'AirtimeFile.artist_name')
)
),
),
'conditions' => array('AirtimePlaylist.id' => 5),
'fields' => 'AirtimePlaylist.id', 'AirtimePlaylist.name'
));
It seems however that the join between CC_PLAYLISTCONTENTS and CC_FILES is not quite playing ball. CC_PLAYLISTCONTENTS should join CC_FILES with CC_PLAYLISTCONTENTS.file_id = CC_FILES.id but it seems to be doing CC_PLAYLISTCONTENTS.id = CC_FILES.id
AirtimePlaylist.php
class AirtimePlaylist extends AppModel {
public $useTable = 'cc_playlist';
public $actsAs = array('Containable');
public $hasMany = array('AirtimePlaylistContent' => array(
'className' => 'AirtimePlaylistContent',
'foreignKey' => 'playlist_id'
));
AirtimePlaylistContent.php
class AirtimePlaylistContent extends AppModel {
public $useTable = 'cc_playlistcontents';
public $hasOne = array('AirtimePlaylist' => array(
'className' => 'AirtimePlaylist',
'foreignKey' => 'id'
),'AirtimeFile' => array(
'className' => 'AirtimeFile',
'foreignKey' => 'id'
));
AirtimeFile.php
class AirtimeFile extends AppModel {
public $useTable = 'cc_files';
public $hasMany = array('AirtimeFileAttribute' => array(
'className' => 'AirtimeFileAttribute',
'foreignKey' => 'track_id'
));

Related

Cakephp 2.x multiple relationship

i have some troubles with cakephp 2.x and the relationship of the models, i have 3 models, Post, User and Comment.
I would like bind the Post with his User and Comment with his User.
In Post Model:
$belongsTo = array('Comment','User'),
$hasMany = array('CommentOfPost'=>array('className'=>'Comment'));
I have Post bind with User, and all comment from the post but i don't have users of the comments.
Edit :
Sql output
1 SELECT `Post`.`id`, `Post`.`title`, `Post`.`content`, `Post`.`tags`, `Post`.`created`, `Post`.`modified`, `Post`.`user_id`, `User`.`id`, `User`.`username`, `User`.`password`, `User`.`role`, `User`.`name`, `User`.`lastname`, `User`.`birthdate`, `User`.`email`, `User`.`created`, `User`.`modified` FROM `blog`.`posts` AS `Post` LEFT JOIN `blog`.`users` AS `User` ON (`Post`.`user_id` = `User`.`id`) WHERE `Post`.`id` = 16 LIMIT 1 1 1 0
2 SELECT `CommentOfPost`.`id`, `CommentOfPost`.`post_id`, `CommentOfPost`.`user_id`, `CommentOfPost`.`content`, `CommentOfPost`.`created` FROM `blog`.`comments` AS `CommentOfPost` WHERE `CommentOfPost`.`post_id` = (16)
Edit :
Comment Model
public $belongsTo = array('User' => array('className' => 'User'));
Post Model
public $belongsTo = array('Comment' => array('className' => 'Comment'));
Edit :
Thank for reply, i have the same result like before i have Post and his User and Post and his comments but not users of comments
Now my model Post
$hasMany = array(
'Comment' => array(
'className' => 'Comment',
)
),
$belongsTo = array(
'User' => array(
'className' => 'User',
)
);
User model
$hasMany = array('Comment' => array('className' => 'Comment'));
Comment Model
$belongsTo = array('Users' => array('className' => 'User'), 'Posts' => array('clasName' => 'Post'));
I use paginate querying in my PostsController
$this->Paginator->settings = $this->paginate;
$data = $this->Paginator->paginate('Post');
$this->set('posts', $data);
Edit :
My paginate params
$paginate = array(
'limit' => 10,
'recursive' => 2,
'order' => array(
'Post.id' => 'desc'
)
);
I try with and without recursive option
Ok it's done !
For resume i have :
class User extends AppModel {
public $hasMany = array('Comment' => array('className' => 'Comment'));
}
class Post extends AppModel
{
$hasMany = array(
'Comment' => array(
'className' => 'Comment',
)
),
$belongsTo = array(
'User' => array(
'className' => 'User',
)
);
}
class Comment extends AppModel {
public $belongsTo = array('User' => array('className' => 'User'), 'Post' => array('clasName' => 'Post'));
}
PostsController extends AppController
{
....
$this->Post->recursive = 2;
$post = $this->Post->findById($id);
...
}
Thank for your help guys, you're awesome !
Post does not belongs to Comment. It has many comments.
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html
Example from the cookbook:
class User extends AppModel {
public $hasMany = array(
'MyRecipe' => array(
'className' => 'Recipe',
)
);
}
For your application:
class Post extends AppModel {
public $hasMany = array(
'Comment' => array(
'className' => 'Comment',
)
);
public $belongsTo = array(
'User' => array(
'className' => 'User',
)
);
}

Cakephp Self referring Model Not working

I have a table
Medias:
ID,
PARENT_ID
PATH
TITLE
Items:
ID
medias
Title
description
Models
class ImageGallery extends AppModel {
public $name = 'ImageGallery';
public $useTable = "medias";
var $belongsTo = array(
'Parent' =>
array('className' => 'ImageGallery',
'foreignKey' => 'parent_id',
'dependent' => false,
),
);
var $hasMany = array(
'Children' =>
array('className' => 'ImageGallery',
'foreignKey' => 'parent_id',
'dependent' => false,
),
);
}
class Item extends AppModel {
public $useTable = "items";
public $validate = array(
'title' => array(
'rule' => 'notEmpty'
),
);
public $belongsTo = array(
'Gallery' => array(
'className' => 'ImageGallery',
'foreignKey' => 'medias'),
);
public $hasMany = array(
'ItemMeta' => array( 'className' => 'ItemMeta'),
);
}
The media table contains gallery information. Images are stored in parent_id relation.
When I request Item->find('all'); I am getting only one entry from Media table, but I want to get all its children too. :(
I can get its children by using $this->ImageGallery->findById(10);, but I want to get them with the Item Model.
Use the containable behavior to specify which associated models you want the query to get. http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html
$this->Item->find('all', array('contain' => array('ImageGallery' => array('Children'))));
If you're looking to go deeper than just the child level, like if you want to get the rest of the tree, then you'll need to either write something to recursively fetch the children, the children's children, etc., or perhaps you can alter your code and models to make use of CakePHP's Tree Behavior. See http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html and http://www.dereuromark.de/2013/02/17/cakephp-and-tree-structures/

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

Cannot save associated data with hasMany through (Join Model)

Hi, I am new to cakephp and doing a project on cakephp 2.3.4.
I have to associate product metal class through has many through association . But it doesn't seem to be working.
Model code
class Metal extends AppModel {
public $hasMany = array(
'MetalProduct'
);
}
class Product extends AppModel {
public $hasMany = array(
'MetalProduct'
);
}
App::uses('AppModel', 'Model');
class MetalProduct extends AppModel {
public $belongsTo = array(
'Metal' => array(
'className' => 'Metal',
'foreignKey' => 'metal_id'
),
'Product' => array(
'className' => 'Product',
'foreignKey' => 'product_id'
)
);}
My database table names are metal, products and metal_products
I have multiple select option for selecting more than one metal type.
This is how I get the the list of metals
$metals=$this->Metal->find('list');
$this->set(compact('metals'));
FormHelper code for listbox is
<?php echo $this->Form->input('Metal',array('type' => 'select',
'multiple' => true)); ?>
The product is getting saved successfully but the associations are not.
The debug array give me this
$message = array(
'Product' => array(
'category_id' => '517a514b-0eb0-4ec9-b018-0b948620d4f0',
'name' => 'mangalsutra Diamond',
'slug' => 'mangalsutra_diamond',
'description' => '1212',
'Metal' => array(
(int) 0 => '5183cb65-bf90-459c-b22e-0b748620d4f0',
(int) 1 => '5183ce25-c744-433e-b035-0b748620d4f0'
),
'image' => '121212',
'price' => '12121',
'weight' => '12',
'active' => '1',
'category' => 'Mangalsutra'
)
)
I had put my head through walls but no clue why the associations are not getting saved.
The way they say in tutorials it seems easy, but why its not working?
I have doubts that its not saving because the metal array is passed like this
'Metal' => array(
(int) 0 => '5183cb65-bf90-459c-b22e-0b748620d4f0',
(int) 1 => '5183ce25-c744-433e-b035-0b748620d4f0'
),
It should mention 'id''rather than (int) 0 or something.
Also, my database table for metal_products which I have created manually has
id(primary key)
metal_id(foreign key to Metal.id)
product_id(foreign key to Product.id)
Am I doing something wrong with naming conventions or the way database is created?
Please give me correct ans cause anything I tried from others answer is not working
I am saving it via
$this->Product->saveAll($this->request->data, array('deep' => true))
In your model, is all of that in your MetalProduct Model? If so you need to move
class Metal extends AppModel {
public $hasMany = array(
'MetalProduct'
);
}
to the Metal model and
class Product extends AppModel {
public $hasMany = array(
'MetalProduct'
);
}
to the Product Model
Also add your belongsTo to each Model
I see you have a join table. Join tables are usually for HABTM associations. This is a HasMany. You need to use the other options available to define the foreign key relationships in each model as outlined above.
Please see the examples on the Cake Documentation.
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html
Also, if you are unsure of how to set up the models correctly, you can always use the Bake feature of Cakephp to generate the models and code for you in that regard.
book.cakephp.org/2.0/en/console-and-shells/code-generation-with-bake.html
If you are more of a visual learner this video tut should help you through the basics
http://www.youtube.com/watch?v=kJAMifqF5s8
The Relation i generated using Bake looks something like this
class Product extends AppModel {
/**
* hasAndBelongsToMany associations
*/
public $hasAndBelongsToMany = array(
'Metal' => array(
'className' => 'Metal',
'joinTable' => 'metals_products',
'foreignKey' => 'product_id',
'associationForeignKey' => 'metal_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
));
}
class Metal extends AppModel {
/** hasAndBelongsToMany associations */
public $hasAndBelongsToMany = array(
'Product' => array(
'className' => 'Product',
'joinTable' => 'metals_products',
'foreignKey' => 'metal_id',
'associationForeignKey' => 'product_id',
'unique' => 'keepExisting',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
));
}
/**
* MetalsProduct Model
* #property Product $Product
* #property Metal $Metal
*/
class MetalsProduct extends AppModel {
/* belongsTo associations */
public $belongsTo = array(
'Product' => array(
'className' => 'Product',
'foreignKey' => 'product_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Metal' => array(
'className' => 'Metal',
'foreignKey' => 'metal_id',
'conditions' => '',
'fields' => '',
'order' => ''
));
}
This worked for me flawlessly.
Hope it works for all.

How to find data through foreign key in cakephp?

Product Plan ProductPlan
id |name id |name id | product_id | plan_id
1 aplha 1 a 1 1 2
2 bravo 2 b
3 charlie
I want to find Product name and Plan name against ProductPlan, if product id and plan id for product exist in ProductPlan then the name of plan and product will show, I tried a lot, the relation b/w tables are correct but i didn't get the exact data, query which i used that is
$p_plan = $this->ProductPlan->find('all',array(
'conditions'=>array(
'ProductPlan.product_id'=>'Product.product_id'
)
)
);
$this->set('p_plan', $p_plan);
if some body help me , i'll very thaksful to him. Thanks in advance.
Relation
For Plan
class Plan extends AppModel{
public $primaryKey='plan_id';
public $hasMany = array(
'ProductPlan'=>array(
'className' => 'ProductPlan',
'foreignKey' => 'plan_id'
)
);
Product
class Product extends AppModel{
public $primaryKey='product_id';
public $hasMany = array(
'ProductsUser'=>array(
'className' => 'ProductsUser',
'foreignKey' => 'product_id'
),
'ProductsUserNode'=>array(
'className' => 'ProductsUserNode',
'foreignKey' => 'product_id'
),
'ProductPlan'=>array(
'className' => 'ProductPlan',
'foreignKey' => 'product_id'
)
);
for Product Plan
class ProductPlan extends AppModel{
var $primaryKey='product_plan_id';
public $belongsTo = array(
'Product' => array(
'className' => 'Product',
'foreignKey' => 'product_id'
),
'Plan' => array(
'className' => 'Plan',
'foreignKey' => 'plan_id'
)
);
public $hasMany = array(
'ProductPlansUserNode'=>array(
'className' => 'ProductPlansUserNode',
'foreignKey' => 'product_plan_id'
),
);
}
You should simply be able to use 'contain':-
$p_plan = $this->Product->find('all', array(
'contain' => array('Plan')
));
This will return all your products, with their associated plans. Your Product and Plan models need a hasAndBelongToMany relationship. There is no need to define a model for your joins table.
class Product AppModel {
...
public $hasAndBelongsToMany = array('Plan');
...
}
class Plan AppModel {
...
public $hasAndBelongsToMany = array('Product');
...
}
As a side note I'd personally avoid overriding CakePHP's default way of handling primary keys. It is better to stick with convention and use id.

Categories