CakePHP find list of associated items where id is - php

I want to create in cake php application with users, games and games platforms (for ex PS3)
I got tables:
userGames (game have one platform)
id, name, platform_id
users (users can have many platforms)
id, username
platforms
id, name
users_platforms
id, platform_id, user_id
And now i want to select all user id=1 platforms, and list it for select tag.
Here is sql query:
SELECT platforms.name, platforms.id FROM platforms LEFT JOIN platforms_users ON platforms_users.platform_id=platforms.id WHERE platforms_users.user_id=1
But i dont know what to list this by find('list') function in cakePHP
I try type in users controller:
$this->User->Platform->find('list', array('conditions', array('User.id'=>'1')));
But this returns sql problem (undefinded User.id)
Anyone can help me?

please try this
$this->loadModel('UserPlatform');
$this->UserPlatform->bindModel(array(
'belongsTo' => array('Platform')
));
$this->UserPlatform->find('list', array(
'fields' => array('Platform.id','Platform.name'),
'conditions' => array('UserPlatform.user_id'=>'1'),
'recursive' => 1
));

you must apply find function on join table
Your find must same as this:
$this->PlatformUser->find('list',array('fields'=>
array('Platform.name','Platform.id'),'conditions'=> array('PlatformUser.id' => 1)));
Your PlatformUser Model must have:
public $belongsTo = array(
'Platform' => array(
'className' => 'Platform',
'foreignKey' => 'platform_id',
),
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
),
);

What you are trying to do is actually a HasAndBelongsToMany Association.
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html
hasAndBelongsToMany (HABTM)
We’ll need to set up an extra table in the database to handle HABTM associations. This new join table’s name needs to include the names of both models involved, in alphabetical order, and separated with an underscore ( _ ). The contents of the table should be two fields that are foreign keys (which should be integers) pointing to the primary keys of the involved models. To avoid any issues, don’t define a combined primary key for these two fields. If your application requires a unique index, you can define one. If you plan to add any extra information to this table, or use a ‘with’ model, you should add an additional primary key field (by convention ‘id’).
HABTM requires a separate join table that includes both model names.
(This would be the UserPlatform-table if I got that right.)
Make sure primary keys in tables cakes and recipes have “id” fields as assumed by convention. If they’re different than assumed, they must be changed in model’s primaryKey.
class Recipe extends AppModel {
public $hasAndBelongsToMany = array(
'Ingredient' =>
array(
'className' => 'Ingredient',
'joinTable' => 'ingredients_recipes',
'foreignKey' => 'recipe_id',
'associationForeignKey' => 'ingredient_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'with' => ''
)
);
}

Related

Complex ordering in CakePHP using Containable

I`m having a problem with the Containable behaviour.
I would like to know if there is any way to access the contained model attributes for operations like ordering.
For example, I have a model B which belongs to a Model A. I need to order objects of B using an attribute (integer) of A. It would be something like:
'contain' => array(
'A' => array(
'B' => array(
'order' => 'A.integer_attribute'
)
)
)
I know that there are easier ways to do this without Containable, but for reasons which are not worth being detailed here, I need to use it. This is an abstract example, in truth model A belongs to other models and this is just a small part of a deep containable tree.
I'd be very glad with any help!
EDIT
OK, I'll try my best to describe the situation without being unclear:
I have 4 models: User, Category, Field and UserField, and their relationships are as follows:
Category hasMany User
Category hasMany Field
User hasMany UserField
Field hasMany UserField
The opposite of these relations are all belongsTo. The purpose here is that the user belongs to a category, which has many fields that he needs to fill with his information (city, state etc). The information he fills is stored in the UserField table, as each information needs to have its field and the user who provided it.
That said, I need to build a screen which displays, for each category, a list of users and their information. So, I retrieve all the categories and its fields, so I can build a table for each category. Each field has an attribute "no_order", which is the number that indicates the order in which the field appears.
At the same time, I need all of each category's users to display them correctly in the tables. Finally, and there's the problem, I need to have UserField objects ordered by the "no_order" of their respective fields, for each user. So I ended up with something like:
$categories = $this->Category->find('all', array(
'order' => 'Category.name',
'contain' => array(
'Field',
'User' => array(
'UserField' => array(
'order' => 'Field.no_order'
)
)
)
));
But this doesn't work, since UserField cannot reach its respective Field's no_order from there.
I apologize if this wasn't clear enough, but for anyone who would spend a little while reading this, I would be VERY grateful for your help!
I am not shure for what do you want so, but I thing that should use joins of cakephp
$A = $this->A->find('all', array(
'joins' => array(
array(
'table' => 'B',
'alias' => 'B',
'type' => 'LEFT',
'conditions' => array(
'B.field_id = A.id'
)
)
),
'conditions' => array(
'B.field' => 'if_you_want_more_conditions'
),
'contain' => array(
'A' => array(
'B' => array(
'order' => 'A.integer_attribute'
)
)
),
'fields' => array('A.field','B.field'),
'recursive' => -1
));
I finally came up with a solution. I don't know how efficient it is, but there it goes:
'contain' => array(
'Field',
'User' => array(
'User.privilege = "Solicitante"'
'UserField' => array(
'order' => '(SELECT f.no_order FROM fields AS f WHERE UserField.field_id = f.id LIMIT 1)'
)
)
)
Having the raw query solved my problem. Hope it helps anybody who comes across a similar problem!

Link one model more than once

I have a function where a user can request a project. The request has 2 fields for other employees to be added.
It's got a field for a person who is responsible for the project (person_responsible) and the employee who is supposed to attend the opening meeting (person_attending).
What I want to know is, since both these fields (person_responsible and person_attending) will be pulling it's data from hr_employees table, how would I set this up in my Project-Model.
At the moment I have the one field set up like this:
public $belongsTo = array(
'HrEmployee' => array(
'className' => 'HrEmployee',
'foreignKey' => 'responsible_person',
'fields' => 'HrEmployee.employeename',
)
);
How would I set up the other field?
What I do in this cases is to make two associations. Since cake allow to customize relations, you can have two relations to the same model with different names.
public $belongsTo = array(
'ResponsibleEmployee' => array(
'className' => 'HrEmployee',
'foreignKey' => 'responsible_person',
'fields' => 'HrEmployee.employeename',
),
'AttendingEmployee' => array(
'className' => 'HrEmployee',
'foreignKey' => 'person_attending',
'fields' => 'HrEmployee.employeename',
)
);
Change the names to adjust your needs. Now, if your model is set as containable and you retrieve the Project model with those models in it, you'll get something like
array('Project' => array(/*data project*/),
'ResponsibleEmployee' => array(/*name*/),
'AttendingEmployee' => array(/*name*/)
)
(or another variation of that array depending on how the query was made).

cakephp belongsto custom condition issue

I’m using cakephp 1.3 with mysql database and engine is MYISAM, I’m getting problem in relationships. I have two tables name Organization and OrgClasses, these two are associated with mbo_studio_id which is common in both table.
organization
Id(PK), name, mbo_studio_id
org_classes
id(PK), name,date, mbo_studio_id
I’m trying to fetch data on the condition of mbo_studio_id, but it adds another condition by primary key of OrgClasses.
var $belongsTo = array(
'OrgClass' => array(
'className' => 'OrgClass',
'foreignKey' => 'mbo_studio_id',
'conditions' => array('OrgClass.mbo_studio_id' => 'Organization.mbo_studio_id'),
'order' => 'OrgClass.date DESC',
'dependent' => false,
)
);
I get following query
SELECT `Organization`.`id`, `Organization`.`name, `Organization`.`mbo_studio_id`, `OrgClass`.` id`,`OrgClass`.`mbo_studio_id`, `OrgClass`.`name`, `OrgClass`.`date`
FROM `organizations` AS `Organization`
LEFT JOIN `org_classes` AS `OrgClass` ON (`Organization`.`mbo_studio_id` = `OrgClass`.`id` AND `OrgClass`.`mbo_studio_id` = Organization.mbo_studio_id)
Here I don’t want Organization.mbo_studio_id = OrgClass.id condition in query.
Thanks
Then you need to set foreignKey to false:
'foreignKey' => false,
This way it will only use your custom conditions.

PHP/CakePHP : Relation HasOneBelongToOne

I'm trying to figured out what's the best way to make a "Has One Belong to One" relation in CakePHP. Unfortunatly I didn't found anything for helping me on the internet.
I've tried to proceed like that:
Company model :
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
User model :
var $hasOne = array(
'Company' => array(
'className' => 'Company',
//'foreignKey' => 'user_id',
'dependent' => true
)
);
But still cakePHP allow me to create two companies for one user.
And here my database schema :
Company : id, name, ..., user_id
User : id, name, ...
Many thanks
CakePHP can handle the following relationships only:
one to one
one to many
many to one
many to many
Read more here
If you want to do "Has One Belong to One" then use the hasOne feature in both objects.
If each user has only one company and each company belongs to one and only one user, shouldn't they be on the same table?
like:
USER
Id
Name
...
Company
Sorry if I shouldn't ask questions back here but seemed pertinent.
In your database, company table, user_id should be set unique.

Naming convention and joins in CakePHP

Just a few days ago I found out about this miracle called CakePHP so I am pretty green to it.
I need to build a mail application, so I have followed the convention and created:
Database description:
Table of users <user_id (primary key), fname, lname>.
Table of mails <mail_id(primary key), from (foreign key to user_id), to (foreign key to user_id), content, opened>.
My questions:
1) According to the convention, a foreign key should be called related table+'_id'. How should I call the columns if there are two foreign keys that relate to the same table. Like from and to in the mails table.
2) I would like to do an inner JOIN the between the two tables.
Something like:
SELECT user_id, mail_id
FROM users
INNER JOIN mails
ON users.user_id =mails.to AND mails.opened=false.
But I have no clue how to do it.
When you need to do two relations to the same table, you will need to override the default convention. In your example, I would make 2 foreign keys. One named sender_id and one named recipient_id. Then you would join them in the Model like so:
<?php
class Mail extends AppModel {
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $belongsTo = array(
'UserSender' => array(
'className' => 'User',
'foreignKey' => 'sender_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'UserRecipient' => array(
'className' => 'User',
'foreignKey' => 'recipient_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
);
}
?>
Then to do your conditions, you would reference them like so:
<?php
$this->Mail->find(array('conditions'=>array('Mail.opened'=>false)));
?>
...and to filter on the sender and receiver, your conditions would look like:
<?php
$this->Mail->find(array('conditions'=>array('UserSender.some_field'=>$someValue,
'UserRecipient.some_field'=>$someValue)));
?>
I'm not an expert myself, but following info on the CakePHP site will help you further:
Multiple-relations-to-the-same-model

Categories