Relations Of An Relation Objects - Cakephp 2.0 - cakephp

I have three models: User Image Group.
User belongs to an image;
Group belongs to a User (admin)
Group Has and belongs to user;
User has and belongs to group;
User and group model are connected with users_groups table;
When I am viewing a group there is listing the members (Users, this works) I need to extract them images what should I do?

You should use the ContainableBehavior. It will allow you to control what data you pull.
First, add it to your AppModel. I also always set $recursive = -1 so extra data is never pulled. Be careful with doing this with an existing app that relied on $recursive data.
class AppModel extends Model {
public $recursive = -1;
public $actsAs = array('Containable');
}
Then, during a find call, use the 'contain' query key. For example, on your GroupsController:
public function view($id = null) {
$results = $this->Group->find('first', array(
'conditions' => array(
'Group.id' => $id
),
'contain' => array(
'User' => array(
'Image'
)
)
));
}
This will bring in the User information associated with the group, along with the Image information associated with the users.

Related

how can i use two associations at once in cakephp

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.

cakephp: how to display foreign key table field

basically,
database table:
Products: id, name
Comments: productId,comment
Model:
product.php
class Product extends AppModel {
public $hasMany = array('Comment'=>array('foreignkey'=>'productId'));
}
comment.php
class Comment extends AppModel {
public $belongsTo = array('Product');
}
In product index.ctp, how can I display one product comment? What I need to write in ProductsController.php and index.ctp?
If you follow the CakePHP conventions (CakePHP Convention over Configuration) then all of this will be done automagically for you, it requires foreign keys to be named product_id rather than productId (although you have setup the foreign key in the relationship - it is just easier to start from the beginning following the conventions).
You should also specify the class name in the relationship:
public $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'foreignKey' => 'product_id'
)
);
In your case what you should do in the controller is:
$products = $this->Product->find('all');
This will fetch all your products and any associated comments on those Products (and also any other associated models you have declared in the Product Model)
If you want to read more about setting this up you can check out CakePHP - Retrieving your data

Cakephp 2 - Most simple associations

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.

CakePHP 2 separate login tables

I have a Cake website and it needs to have two separate logins, each one will have their own login form and see different pages, it would be nice to have two different tables because there are no similarities between the two types of people.
Each login form will only be used by certain people and they will never login to the other form, and vice versa.
Also, the two login tables have a relationship between them, which requires 2 tables?
Is this possible?
First, add a couple of empty custom authenticate objects. We'll reuse the same logic that FormAuthenticate uses (that is, uses POST data to check the database for a user), but simply change the model within the object settings (later).
app/Controller/Component/Auth/ModelOneAuthenticate.php
<?php
App::uses('FormAuthenticate', 'Controller/Component/Auth');
class ModelOneAuthenticate extends FormAuthenticate {
}
app/Controller/Component/Auth/ModelTwoAuthenticate.php
<?php
App::uses('FormAuthenticate', 'Controller/Component/Auth');
class ModelTwoAuthenticate extends FormAuthenticate {
}
Then tell your app to use these objects to authenticate, and tell it what model to use. You can also customize the fields here. In your AppController:
public $components = array(
'Auth' => array(
'authenticate' => array(
'ModelOne' => array(
'userModel' => 'ModelOne',
'fields' => array(
'username' => 'my_custom_username_field',
'password' => 'some_password_field'
)
),
'ModelTwo' => array(
'userModel' => 'ModelTwo'
)
)
)
);
The first authentication object would check the model_ones table for a username in my_custom_username_field and password in some_password_field, while the second one would check model_twos using the standard username and password fields.
The simplest way to do this is to just set a different session key for each login type:
if ($loginTypeOne) {
$this->Auth->authenticate = array(
'Form'=> array(
'userModel'=> 'TypeOne',
)
);
AuthComponent::$sessionKey = 'Auth.TypeOne';
} else {
$this->Auth->authenticate = array(
'Form'=> array(
'userModel'=> 'TypeTwo',
)
);
AuthComponent::$sessionKey = 'Auth.TypeTwo';
}
When they have to login there is a similarity: Both will require it to enter credentials, usually an username/email and password. So a users table and a foo_profiles table and a bar_profiles table depending on the user type should work also.
If you really want to go with two total different tables and the MVC stack for them, then simply use two different controllers FooUsers and BarUsers and inside of each create a customized login method.
I have done this previously by writing custom Authentication components that extend from BaseAuthenticate. As long as they implement the authenticate() method then you'll be able to do whatever you want to each of the different types of user.
In your AppController you need to register the different components by doing something like
public $components = array(
"Session",
"Auth" => array(
'authenticate' => array("UserType1", "UserType2"),
)
);
Check out the cookbook for the rest of it.
You can have a look on this.
Define Model for both login member and then define table which you want to use for the user.
set variable in model.
class SearchedCategory extends AppModel {
var $name = 'SearchedCategory';
Var useTable = 'give your table name here.';
var $primaryKey = 'id';
}

CakePHP - How to retrieve deeply associated data?

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'))));

Resources