I have two tables clients and users, users belong to clients. In UsersTable.php I want to set $ this-> setDisplayField ('Clients.name'); but it does not work. What is the way to do this?
You should try to set display field not by classname, but by name of contained entity:
$this->setDisplayField('client.name');
Of course in this case, you should contain Clients model in your query.
$result = $this->Users->find('list')->contain('Clients');
Its possible also in deeper relations.
// model
$this->setDisplayField('client.address.street');
//query
$result = $this->Users->find('list')->contain('Clients.Addresses');
I tested it only in belongsTo relation.
Related
I'm currently optimizing my application and one thing is selecting only the things from database which are really needed.
For example when I'm retrieving a User object I normally do it like this:
$user = User::where($attribute, '=', $value)->first();
This code will give me back a full user object with all the columns. My users table is pretty big, so I thought it is a good idea to only select the columns which I need like this:
$user = User::where($attribute, '=', $value)->first($columns);
This is also working as expected. But my problem is, as soon as I specify columns, the relationships of the $user variable are not working anymore, because it is no longer an object.
My question: Is it possible to select only a few columns but still be able to use relations like
$user->parents
Thanks!
Try This
$user = User::where($attribute, '=', $value)->select($columns)->first();
Just add all foreign keys for the relationships you want to get. For example, if you want to use parent() relationship, just add the key to the $columns:
array_push($columns, 'parent_id');
After that, you'll be able to use the parent() relationship.
Yes it is possible to load relationship with selected columns but for that you have to select foreign keys of that relationship table.
So here you also have to select the column of user table which is foreign key in parents table and also mention relationship using with(),
For example if you have user_id column in parents table as foreign key then you have to select id column of user while you are mentioning columns array in first() method as below:
$user = User::with('parents')->where($attribute, $value)->first(['id','email','image']); // also select 'id' for foreign key to load relationship
After using above code you can get relationship of parents as: $user->parents, and don't forget to put relationship in your User Model.
If you have foreign key on user table as parent_id which belongs to parents table then you have to select that parent_id column as below code:
$user = User::with('parents')->where($attribute, $value)->first(['parent_id','email','image']);
I have a bunch of models that I'm going to be creating, and these models will have different types of categories that they can belong to. For example, one model will HABTM one set of categories, another model will HABTM another set.
I've come up with one idea - creating a model called Category, and having a categories table with a 'model' field, that contains the name of the model that this category has a HABTM relationship with. Then the other models would have something like this:
public $hasAndBelongsToMany = array(
'Category'=>array(
'conditions'=>array(
'Category.model'=>'Modelname'
)
)
)
This seems OK but
this code will be repeated in every model which seems silly and
some categories will apply to several models, so there would be duplicate database entries for those categories.
Is there a better way? Thanks for your help!
You can use one category model and add a model field to the category model to specify the related model. So you can use different models with one category model... Like you said...
I think this is a good idea.
i think i have all 'baked' all my relationships correctly but my 'related' table shows id's instead of values.
my db has 3 tables. candidates, qualificationlookups, qualifications.
qualificationlookups, links candidates to qualifications using the id of the candidate and the id of the qualification.
in my view view, for 'candidates', i have a 'related qualificationlookups' table. (generated by baking a candidate hasmany qualificationlookups and a qualificationlookups belongsto candidate relationship)
in my edit view, for 'qualificationlookups', i can correctly set up the candidates and qualifications fields as dropdowns so i know 'qualificationlookups's relationships are fine.
So how do i ask cakephp to list the name of the qualification (from 'qualifications' table) in the 'related qualificationlookups' table on a candidate's page?
i must be missing something...
could someone please point me in the right direction?
Thanks, Vauneen
Whenever CakePHP automagically fetches lists from your tables, it uses the id key for the value and the $displayField for the text.
If your table has a name or title field, CakePHP automatically displays it as the display field. So, either rename the field that you want as your display field (say, candidate_name to just name) or set the $displayField variable in your model:
class Candidate extends AppModel {
var $displayField = 'candidate_name';
}
HTH.
If there is no other data being stored in the qualificationlookups table, change the relationship to candidates -> HABTM -> qualifications.
To do this, you first need to drop the qualificationlookups table. Create a new table called candidates_qualifications with two indexes, candidate_id and qualification_id.
In your Candidate and Qualification models, define a HABTM Relationship. You do not need to make a new CandidatesQualification Model, cake will do it on the fly.
I was hoping someone with an understanding on CakePHP could shed some light on a question I've been having.
Here's my scenario, I have a User this User has a Company which in turn has many Department and many Address. If I were to get a User could I expect to have access to the Company and all models associated with that Company?
So would $user['Company']['Department'][0] or $user['Company']['Address'][0] be possible?
Which brings me back to the original question, how extensive is the linkage between models?
In plain-vanilla model, Cake's model linkage is determined by your models' recursive attribute. Your example model relationship looks something like this:
User
-> belongsTo Company
-> hasMany Department
-> hasMany Address
-> hasMany PhoneExtension
(I've added an additional relationship (User hasMany PhoneExtension) to flesh out the following explanation.)
There are three accepted values for Model::recursive: -1, 0, 1 and 2. Each value indicates to Cake's ORM a different depth to retrieve model records. I'll use $this->User->find('all') to illustrate the difference.
At recursive = -1, Cake retrieves only the specified model (ie. User). It parses none of the model associations.
At recursive = 0, Cake retrieves the specified model, and parses its belongsTo associations. $this->User->find('all') would retrieve all User records, as well as the Company record to which each User belongs.
At recursive = 1, Cake retrieves the specified model, and parses all of its direct associations. $this->User->find('all') would retrieve all User records, as well as the Company record to which each User belongs, and all PhoneExtension records belonging to the User.
At recursive = 2, Cake retrieves the specified model, parses all of its direct associations and all associations of its direct associations. $this->User->find('all') would retrieve everything in the example model relationship diagram: all User records, the Company records to which the User records belong, all PhoneExtension records belonging to the User, and all Department and Address records belonging to the Company.
Which is the very long way of saying that yes, you can achieve the results you indicate in your question, at recursive = 2.
If you wanted to go deeper than what recursive = 2 gets you, you'll have to use the Containable behaviour. Let's say that your Department model had an additional association: hasMany Group. Thus:
User
-> belongsTo Company
-> hasMany Department
-> hasMany Group
-> hasMany Address
-> hasMany PhoneExtension
To retrieve everything we got with a recursive = 2 retrieval, as well as all the associated Group records, you'd construct your Model::find call like this:
$this->User->find('all', array(
'contain' => array(
'PhoneExtension',
'Company' => array(
'Department' => array( 'Group' ),
'Address'
)
)
));
It's as extensive as you need/want it to be. Look into the recursive option of the find() family of methods. Also the Containable behavior. The specific references you list are possible, but directly under the user:
$user['Department'][0]
Think of it as the user having many departments through its company.
If you access a class/object and set "$this->recursive = -1" then it only returns the object without the dependencies!
I have a HABTM relationship between Users and Locations. Both Models have the appropriate $hasAndBelongsToMany variable set.
When I managing User Locations, I want to delete the association between the User and Location, but not the Location. Clearly this Location could belong to other users. I would expect the following code to delete just the join table record provided the HABTM associations, but it deleted both records.
$this->Weather->deleteAll(array('Weather.id' => $this->data['weather_ids'], false);
However, I am new to CakePHP, so I am sure I am missing something. I have tried setting cascade to false and changing the Model order with User, User->Weather, Weather->User. No luck.
Thanks in advance for any help.
Not quite sure how Weather is related to your models, so I'll just go with the traditional names, LocationsUser is the joining table. This should delete all associations between the user with id $id and any locations:
$this->User->LocationsUser->deleteAll(array('LocationsUser.user_id' => $id), false);
Notice also that you're missing a closing bracket in your code snippet.