CakePHP hasAndBelongsToMany (HABTM) Delete Joining Record - cakephp

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.

Related

CakePHP find items with hasOne Model relation that have no associated item

I have a user model which has a hasOne relation with a profile model. I want to find the users which have no profile associated with them. I don't know whether the counterCache works for hasOne relation or there is a better way with appropriate conditions.
I believe that the hasOne relationship creates a LEFT JOIN in the SQL statement. Arguably, the generated SQL for your find would look something like (assume there are more columns though):
SELECT User.id, User.name, Profile.id
FROM users AS User
LEFT JOIN profiles AS Profile
ON Profile.user_id = User.id;
All you need to do is add another WHERE clause: WHERE Profile.id IS NULL for unmatched rows. Thus changing your Cakephp code to
$this->User->find('all',array(
'conditions' => array('Profile.id' => 'NULL')))

cakephp Model Relationships

I have an acl controlled cake application and specifically there are two tables I am having an issue with: 'users' and 'forms'. All of my tables have a 'created_by' field which links back to users giving me the user id of the records author. This is set on save within the forms model from Auth.
The issue I have is that each form record must be authorised by a user with a role of manager prior to being visible on site. I have therefore included a 'signoff_id' field which needs to relate back to the user table id.
In my Form model I have included the following
public $hasOne = array(
'User'=>array(
'className'=>'User',
'foreignKey'=>'created_by'
),
'Signoff'=>array(
'className'=>'User',
'foreignKey'=>'signoff_id'
),
'Db',
'Identity'
);
This works ok with created_by and I get the correct info back from finds, but signoff_id is looking for a Signoff.signoff_id field (and trying to bring back all of the User table fields but substituting Signoff for User.
Any ideas gratefully received - I've tried the RT(F)M option but am no further forwards.
Finally joined the dots together ...
my Form model links back to the User model with a foreign key of 'id', and the User model links to Form with a foreign key of 'signoff_id'
Simple now I've sorted it.

Deleting association from HABTM table

I have a Users and a Reports table, connected with HABTM relationship.
I can save a report that creates a correct record in reports_users table, I can view the relationship table by using $this->User->ReportsUser->.., and so on.
Now I want to delete a specific row in reports_users table, but I can't seem to do it.
I have tried the following:
$this->User->ReportsUser->deleteAll(array(
'ReportsUser.report_id' => $this->data['Report']['report_id'],
'ReportsUser.user_id' => $this->data['Report']['user_id']
));
..but it deletes all the rows with the given user_id, with this query:
What am I doing wrong here. Is it a bad data in the deleteAll call?
I don't want to delete any users or reports, only the relationship between them.
I can confirm that the table names are correct, and that the variables exist and are set.
It seems no error with your code. Either your $this->data['ReportUser']['report_id'] is having some problem. The best way is to first try to print your $this->data. And check whether it exists?
For the safety reasons, use the second argument $cascade = false and also unbind all the ReportUser model Associationship using $this->ReportUser->unbindModel() method.
The other reason seems to be deleting data through
$this->User->ReportUser. Try to use $this->ReportUser->deleteAll('your conditions', false); directly.
Please ask if it not worked for you.

CakePHP: hasMany with join table

I have two models: Store and Review. Users of my site can leave a review on a store. In my database, I have a join table, reviews_stores that associates a review with a store.
How do I link my models? I assume a Store should haveMany Review, and a Review should belong to a Store, but the join table is causing issues with CakePHP as CakePHP is assuming my reviews table has a column called store_id.
The reason I'm using a join table is because many parts of my site can be reviewed. For example, brands. A new Review record will be created and a record will be inserted into a brands_reviews table to associate the two records.
Any help would be much appreciated.
Why are you not simply using one Review model and a reviews table with a field "foreign_key" and another field "model"? By this you do not need to duplicate tables and inherit or duplicate models. This will also remove the need for a join table.
If you want to continue to use your db design then you'll have to use a HABTM association over the hasMany association. But even in the case you want to keep that jointable, again, you can use the foreign_key/model and simply have one join table and one reviews table.
By the way, your join table review_store does not follow the conventions, it should be reviews_stores. But then it differs to the schema you've used for brands_reviews. ;)
Seems to me it isn't a many-many relationship but a grouped 1-many relationship. Id lose the join tables and simply have an extra table outlining which 'group' the review belongs to. So the review table would have review_id, link_id(the foreign key for the relevant brand or store), review_type_id(foreign key depicting whether the review is for a brand or store and so on). Then the review_type table only needs to have review_type_id, review_type(varchar).
There's no need for all the join tables for each model you can review, simple store the model name itself in a field in the Review table.
Setup your relationship like so:
class Store extends AppModel {
public $hasMany = array(
'Review' => array('conditions' => array('Review.model' => 'Store')
);
}
You can then do this with as many extra models as you like without having to touch the database.

CakePHP automatically remove associated items

this may be a rookie question for CakePHP but here it goes
I design 3 models with associations:
'Client' hasMany 'Invoice' hasMany 'Item'
So when we do a read from Client, it will automatically grab related Invoices.
What if we try to delete a Client, is there a way so that CakePHP will automatically delete all related entries in 'Invoice' and subsequently all related entries in 'Item' ?
Yes, if the association is declared as dependent.
See http://book.cakephp.org/view/1043/hasMany.

Resources