i'am using cakephp 2.x
i have two tables USERS and JOBS in my database,
in users table i save two types of users job candidate and company in this situation i found my self facing two relations between the tables :
(1,n)users can add (0,1)jobs. (user role here is Company)
many (1,n)users can apply to many (1,n)jobs. ( Candidate)
can i use belongsTo and HABTM(hasAndBelongsToMany) at once between the two models ?
like this :
Job model
Class Job extends AppModel{
public $belongsTo=array(
'User'=> array(
'className' => 'User',
'foreignKey' => 'user_id',
'counterCache'=>true,
'fields'=>array('id','username','role'),
)
);
public $hasAndBelongsToMany=array('User');
public $usetable = 'jobs';
User Model
Class User extends AppModel{
public $hasAndBelongsToMany=array('Job');
how to retrieve data depending on the first or the second context
1- show all jobs of company.
2- show users applies.
You can do this, but the two associations need different aliases. So you could refer to an User appling for a Job as an Applicant:-
class Job extends AppModel {
public $belongsTo = array(
'User'=> array(
'className' => 'User',
'foreignKey' => 'user_id',
'counterCache' => true,
'fields' => array('id', 'username', 'role'),
)
);
public $hasAndBelongsToMany = array(
'Applicant' => array(
'className' => 'User'
)
);
}
Note that you need to tell Cake that the Applicant uses the User model via the className property. For your belongsTo association you don't need to specify the className for the User as it is the same as the alias is the same as the model name but I have left it in for clarity.
You also don't need to specify $usetable = 'jobs as this is implied by using the correct naming conventions.
Related
Hello there,
thanks in adv for help.
i have two table: named as options fields are (id,option_title,created,status) and second table as option values fields as (id,option value,options_id,created,status). THe option values table has a foreign key as options_id. Now when i created association between these two table . i didn't work.. Let me explain you how i am creating association.
In the Option model i am using following code.
var $hasMany = array(
'values' => array(
'className' => 'Optionvalue',
'foreignKey' => 'options_id'
));
But this is not working and i am not able to get data from options table. Can any please advice me.. where i am wrong. I just need options table data in the optionsvalue add view file.
Assuming you have a table called options and another called optionvalues. Here is how the Option model looks like
class Option extends AppModel {
public $hasMany = array(
'Optionvalue' => array(
'className' => 'Optionvalue',
'foreignKey' => 'option_id',
'dependent' => FALSE
)
);
}
In the Optionvalue model you then go like this
class Optionvalue extends AppModel {
public $belongsTo = array(
'Option' => array(
'className' => 'Option',
'foreignKey' => 'option_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
}
This is how it should look like. In the Optionvalue Add method, you will need to write this in the view
echo $this->Form->create('Optionvalue');
echo $this->Form->input('option_id');
echo $this->Form->end('Save');
and the options will appear by themselves.
Very important though, you did not follow the naming conventions. options_id needs to be option_id among others.
Use
option_id in place of 'options_id'
Cakephp strongly follows naming conventions.
http://book.cakephp.org/2.0/en/getting-started/cakephp-conventions.html
Also looks like you are not using proper naming conventions for other places too.
I'm facing trouble telling cake the most simple associations.
I have two Models:
CoreUser.php
CoreRole.php
.
One User has one Role.
How to assign that in cake? (HasOne or BelongsTo? => When to choose what?)
What to put in what Model? I tried both and ever end up with a recursion-error or it is just not working.
My SQL-Tables:
(tbl) core_users [id,username,password,role_id]
(tbl) core_roles [id,name]
My Models:
class CoreUser extends AppModel {
public $hasOne = array(
'Role' => array(
'className' => 'CoreRole',
'foreignKey' => 'id'
)
);
}
class CoreRole extends AppModel {
public $belongsTo = array(
'User' => array(
'className' => 'CoreUser',
'foreignKey' => 'role_id'
)
);
}
=> Can you give me the correct code i need to insert into one of both (or both) models to tell cake about the relationship?
Thanks in advance
Theoretically, there are two things you need to think about, one of them being non-Cakephp specific.
A. Relationships: A relationship is always bidirectional. When determining the relationship between two Models/Objects/Tables, you always ask two questions:
How many instances of B are related to one instance of A?
How many instances of A are related to one instance of B?
You've said, One user has one Role. However, One Role has how many Users related to it? That will tell you the complete relationship between a User and a Role. (Apologies for the digression but this is important and I'm referencing this book.)
B. Difference between hasMany and belongsTo:
This is determined based on the direction of traversing a relationship.
Based on point A, say you've determined that:
One User has one Role but One Role has many Users.
Now when you are in the User's model trying to fetch related Role data, you need to define the following in the User model:
class CoreUser extends AppModel {
public $belongsTo = array(
'Role' => array(
'className' => 'CoreRole',
'foreignKey' => 'role_id'
)
);
}
But when you are in the Role's model and trying to fetch related User data, you will need to define the following in the Role model:
class CoreRole extends AppModel {
public $hasMany = array(
'User' => array(
'className' => 'CoreUser',
'foreignKey' => 'role_id'
)
);
}
For a full discussion refer to this answer.
I’m writing a CakePHP plugin. In my plugin’s AppModel I have:
public $actsAs = array(
'Containable'
);
I then have two models: a CartItem and a Product. My CartItem model look like this:
<?php
class CartItem extends ShoppingCartAppModel {
public $belongsTo = array(
'Cart',
'Product'
);
}
However, when calling the Cart model in my controller I get the following error:
Warning (512): Model "CartItem" is not associated with model "Product" [CORE/Cake/Model/Behavior/ContainableBehavior.php, line 344]
Why is this, when I’ve defined that my CartItem model is associated to the Product model through a belongsTo association?
EDIT: I’ve narrowed my problem to where I attempt to fetch my cart and its contents in my Cart model. Here is the call:
public function findBySessionId($sessionId) {
$cart = $this->find('first', array(
'conditions' => array(
'Cart.session_id' => $sessionId
),
'contain' => array(
'CartItem' => array(
'Product'
)
)
));
return $cart;
}
Model associations need a plugin prefix
From the question it is likely the Cart Model is defined like so:
public $hasMany = array(
'CartItem'
);
}
This will mean that Cake is expecting the following:
app
Model
CartItem.php <- 'CartItem' means the model is in the App, not a plugin
Plugin
Model
Cart.php
The App CartItem model doesn't exist, and therefore will be an instance of AppModel.
Always ensure that the plugin prefix is used (if appropriate) when defining model associations:
public $hasMany = array(
'ShoppingCart.CartItem' // Load the model from this same plugin
);
}
Figured out the problem. Models in a plugin need the plugin name in the class name.
For example:
<?php
class Cart {
public $hasMany = array(
'CartItem' => array(
'className' => 'ShoppingCart.CartItem'
)
);
}
Specifying the plugin name just in the association name caused an SQL error for me, so you can circumventing by specifying the class name—with plugin prefix—manually.
I got a Table Users and a Table Groups. Every group has one GroupLeader.
So the field i use in is groupLeader ($hasOne) which contains a foreign key of users.
I cant manage to get that relation. So my question is, how to define a relation on a field with a diffent name.
thanks for a hint.
endo
You model should looks:
class Group extends AppModel
{
public $name = 'Group';
public $belongsTo = array('GroupLeader' => array(
'className' => 'User',
'foreignKey' => 'groupLeader'
)
);
}
Try with the above code. And ask if it is not worked for you.
I have the following models:
User:
hasOne Profile, Page
hasMany Comment
Comment:
belongsTo User, Page, Profile
Page:
belongsTo User
hasMany Comment
Profile:
belongsTo User
When I retrieve a page, I want to get the associated Comments, and for each comment I want the Profile.
My comments table has fields page_id and user_id.
My profile table has user_id.
So, I assume I need to do something like
Comment belongsTo
'Profile' => array(
'conditions' => array('Profile.user_id' => 'Comment.user_id')
)
but that's not working - it returns a blank profile record.
I am using CakePHP 2.0.
Use CakePHP's Containable behavior [link]. Basically, this allows you to pick and choose which related models you want to include in your find.
You can also specify which field(s) you want from each model, specify conditions on each...etc.
It should look something like this:
//PageModel
public $actsAs = array('Containable');
public function getPage($id=null) {
$this->recursive = -1; //often set to -1 in the AppModel to make -1 the default
$this->find('all', array(
'conditions' => array(
'Page.id' => $id
),
'contain' => array(
'Comment' => array(
'User' => array(
'Profile',
),
),
)
));
}
If the relations are declared correctly, all the data you need can be retrieved by searching for the desired Page. But to limit the quantity of data returned, you will probably have to use te ContainableBehavior.
PageModel:
var $actsAs = array('Containable');
PagesController:
function view($id)
{
$this->Page->contain(array('Comment' => array('User', 'Profile')));
$page = $this->Page->find('first', array('conditions' => array('Page.id' => $id)));
}
EDIT
Sharon, according to your question it seems that Comments are linked to Users and to Profiles. But if Profile means a "user profile", the link between Comment and User is enough and the contain should then be:
$this->Page->contain(array('Comment' => array('User' => array('Profile'))));