I apologize in advance... I'm a complete noob to cakephp. As such, I'm having great difficulty in getting my models related correctly. To be more specific, I'm having the most trouble with the "hasMany Through" relationship. I've been beating my head against the wall, and scouring the cookbook, but haven't found it as clear as i had hoped.
I'm currently writing a web app with many complex relationships. I'll start with stripped down versions of my tables.
Users:
id, name
Groups:
id, name, department_id
Departments:
id, name, district_id
Districts:
id, name
Roles
id, name
Note that roles are what I call my levels of access(user, admin, superuser).
groups_users
-group_id, user_id
departments_users:
department_id, user_id, role_id
RELATIONSHIPS:
User hasAndBelongsToMany Department
Department hasAndBelongsToMany User
User hasAndBelongsToMany Group
Group hasAndBelongsToMany User
Department hasMany Group
Group belongsTo Department
District hasMany Department
Department belongsTo District
Now, here's where i get a bit more confused.
Since users can be in multiple departments, in multiple districts, as well as have varying roles within each department (e.g. Department admin in DEPT A of DISTRICT A, and District Admin in DEPT B in DISTRICT B), I chose to place the user's level of access in the departments_users table. Since I'm storing more than foreign keys for the named models, ie role_id, this seems like a candidate for the hasMany through relationship, but cake's docs also mention a keepExisting option for the model relationship.
so i tried this, using the example from the cake site. leaving all of the initial datatables and relationships in place, I added a DepartmentPosition model and controller, like the following:
user.php
public $hasMany = array('DepartmentPosition');
department.php
public $hasMany = array('DepartmentPosition');
department_position.php
public $belongsTo = array('User','Department');
I also added a new data table:
department_position:
id, department_id, user_id, role_id
OK, so what i got, likely mistakenly from the cake docs, is that when I add a user to a department, i can include a role_id, and that will all be saved in the department_position data table, if I do saveAll().
I'm not sure if that is at all the right thing to do. I feel more confused now, having written this out, than i did before. lol. I'm very confused as to how to get these relationships correctly set-up. And, still, once I do, I feel i'll have trouble accessing data from associated models. I'm getting errors galore and am unable to retrieve much associated model data. eek. like I said, i'm not the strongest cake person.
Any suggestions, before i have an aneurysm?! lol.
Thanks loads. Any help will be a lot of help!
If a User can have different Role in different Group something is needed in between, HABTM or hasManyThrough table.
Before Cake version 2.1, it was not possible to have HABTM relation with extra colums, (here below role_id). The column would get lost when saving. This is not the case anymore if you set the unique param to keepExisting, but I prefer the hasManyThrough relation over HABTM. I guess it's a question of taste.
User hasMany GroupRole
GroupRole belongsTo User, GroupRole belongsTo Groups, GroupRole belongsTo Role (GroupRole is hasManyThrough table)
Group hasMany GroupRole, Group belongsTo Department
Department hasMany Group, Department belongsTo District
District hasMany Department
Related
How to change cakephp concept user belongsTo Group, to user hasMany Group,
apart make new table called users_groups, and what should I change to make my user really have access to many groups that user have?
Make Things Simple:
In such scenario you already needed three tables.
Users table
id
name
phone
Groups
id
group(title)
User_Groups
id
user_id
group_id
As you need relations like user has many groups then you need extra table which at least should include foreign key like user_id, and group_id.So don't hesitate to add extra table for making things simple.
You'd be using 3 tables, and then a HasAndBelongsToMany relationship over the Users_Groups. Users HABTM Groups
I have two Models, departments and users. Departments is associated by hasMany with users and users belongsTo a department. Below is the snapshots of two table structures.
department_id is foreign key in user table.When i delete the department ,the respective department_id in user table not getting deleted.it stays as assigned before.How can i delete the department_id in users table.
Actually, cakephp does not provide a mean to do that. You need to set SET NULL ON DELETE in the database.
I have 3 tables. Here are they with their columns:
Result : id, title
Prospect: id, result_id, customer_id
Customer: id, name, address
Result hasMany Prospect.
Prospect belongsTo Customer.
Customer hasMany Prospect.
Everything's ok. If I view the Result, it would display fine along with its related model Prospect.
But in that related model, I'd like to display the customer name instead of customer_id (by looking up). How to do that?
And how to paginate the related model?
Thank you so very much!
add in Prospect belongsTo Result and you will be able to get the info both directions.
if you want to do more crazy things like finding results based on customer name then you might need to read up on the following
linkable behavior
bindModel
adhoc-joins
I was wondering if this is possible to do with a has many through
contents orgs folders
id id id
name name title
link
join table - folder_elements
id
element_id
order
contents has many folders through folder_elements
orgs has many folders through folder_elements
So my question is, is it possible to use element_id to store the content.id or the org.id ?
Alex
What you're describing is a sort of HABTM (HasAndBelongsToMany) association. You could define the inter-model associations as you suggest, but there's a pretty significant design flaw: how would you account for a situation where the same ID is used for an orgs record and a contents record, and wish to associate them with the same folder record? It would be impossible to differentiate between the two in your joining table.
There are a number of ways to work around this, but they require more program logic or a more disorganised database schema that presents challenges in maintainability.
The more elegant, robust solution is to rationalise your database structure. If there's no pressing need to have One Join Table to Rule Them All, you could design your model associations like this:
Content hasMany ContentsFolder belongsTo Folder
Folder hasMany ContentsFolder belongsTo Content
Org hasMany OrgsFolder belongsTo Folder
Folder hasMany OrgsFolder belongsTo Org
This is the internal structure of a HABTM association defined explicitly so you can define fields in the joining table. Your contents and folders tables would remain the same, but your two joining tables would look like:
contents_folders
-> id
-> content_id
-> order
orgs_folders
-> id
-> org_id
-> order
Unfortunately, yes, this would require defining five models instead of three, but such are the limitations of CakePHP's object-relational modelling.
I apologize if this question has been asked and answered elsewhere but I have looked and have not been able to find it.
I have three models:
Manager HABTM Tenant
I also have a ManagersTenant model to tie the two together.
I'm trying to use pagination to recursively display fields from Manager and Tenant in the ManagersTenant controller. Here is my code:
$this->ManagersTenant->recursive = 2;
$this->set('managersTenants', $this->paginate('ManagersTenant',array(),array('recursive'=>2)));
This displays only the fields in ManagersTenant (id, tenant_id, manager_id) but does not retrieve data from the associated Manager and Tenant models.
I am also doing a debug($this->ManagersTenant->find('all')); which performs the recursion perfectly and displays the right arrays.
What am I doing wrong? Do I need to do anything special with my model(s)?
Any help is much appreciated.
//edit:
What I'm trying to do is display all matches where Tenant_id or Manager_id matches the logged-in user's id. For example, if a logged-in Manager performs the index function on the Tenant model, I would like for all Tenants to be displayed for Tenant_id where Manager_id (in the ManagersTenant model) == $this->Auth->User('id'). I was under the impression that in order to do this, I had to utilize a HABTM table. But if it is possible for me to do Manager HABTM Tenant without a joining table, I am all for trying it.
You probably don't need to define the ManagersTenant model. You should define HABTM in the Manager and in the Tenant model, and use those models for your query.
If you really need a ManagersTenant model you should use the join model relationship:
Manager hasMany ManagersTenant
Tenant hasMany ManagersTenant
ManagersTenant belongsTo Manager and Tenant.