cakePHP hasMany not joining the SQL query - cakephp

I am unable to do a simple condition for my paginator. I have a Survey and Campaign models. Campaigns hasMany Surveys setup in the Campaign model.
I want to select a survey and the paginator should display the campaign is linked to, but I keep getting a Unknown column Survey.id - On inspection I see that Survey is not joined to the Campaign model, only in the WHERE clause. I also found out that hasMany does not join the tables to the query.
How else can I go about doing the above?

I could not find an answer to this. It appears that hasMany does not automatically get added to a query. I have had recommendations that using the containable feature in cake may help.

Related

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 HABTM find all records that have associated records

I have a model - "Category" which HABTM "Blog". I need to create a query that will only select categories that have more zero blogs associated with them. I'm having trouble working out how to do this. All I've come up with is getting the categories out of the database using find('all'...) and then extracting those that have something in the $category['Blog'] array. Obviously I'd much prefer to not have to ask the database to do all that work, so a more elegant solution would be much appreciated.
Thanks for reading!
not really elegant (short), but I think this is the correct way:
add a blogs_category_count field to categories table
add Category hasMany BLogsCategory with counterCache
so you just have to add a condition to that find('all')

Looking up column in related model

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

Recursive Pagination in CakePHP Not Working

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.

CakePHP search in hasMany relations

I have a model Content which belongsTo Categories, hasMany Publishers, and Publisher belongsTo city.
There is also a search form where someone selects from a drop-down box which category to view and which city.
But how can I combine these two in a single paginate condition? I mean I cannot do something like:
$this->paginate('Content',array('conditions' =>array('Category.id'=>$category,
'City.id'=>$city)));
because to get cities cake performs a different query.
Nor can I do something like:
$this->paginate('Content',array('conditions' =>array('Category.id'=>$category),
'contain'=>array('Publisher.City'=>array('conditions'=>array(City.id'=>$city)))));
because this will search according to category and filter the city results according to $city.
I know I can do something like:
$this->Content->Publisher->City->find(...)
but this will change the output of my paginated data.
What I usually do is write my custom query where I LEFT join all models and filter the results in WHERE. But I wanted to aks if there is a more cake (sic) way!
thanks
i've experienced the same thing when i first try to create a simple search engine with hasmany relationship.
i used multiple $this->find() and assigned it in a variable then on the paginate code i used$this->paginate(array_merge(name of the variables used in $this->find()));.
hope this will help you...
~gio

Resources