Cakephp HABTM relation - database

i have theses tables
article , article_currency, currency in database
and i made HABTM between article and currency like this
var $hasAndBelongsToMany = array('currency'=>array('className' => 'currency','joinTable'=>'article_currency','foreignKey' => 'articleid','associationForeignKey' => 'CurrencyID'));
var $hasAndBelongsToMany = array('articlemodel'=>array('className' => 'articlemodel','joinTable'=>'article_currency','foreignKey' => 'CurrencyID','associationForeignKey' => 'ArticleID'));
and here cake genrate the model ArticleCurrency for me
when i try to change its name using with to 'article_currency'
is give me this error
Database table article_currencies for model article_currency was not found.
how i can solve this

Table names are plural by convention: articles, currencies, articles_currencies
http://book.cakephp.org/view/24/Model-and-Database-Conventions

Related

Cakephp naming convention for table

I am new to CakePHP and building my first web project for customer service request.
I have following tables in database...
customers
customer_addresses
customer_service_requests
service_requests
service_requests table has foreign keys:
customer_id
customer_address_id
While baking MVC for service request, I'm getting following errors
Error: Table customers_addresses for model CustomerAddress was not found in datasource default.
The ServiceRequest model has a belongsTo relation as
'CustomerAddress' => arrray(
'className' => 'CustomerAddress',
'foreignKey' => 'customer_address_id',
'conditions' => ' ',
'fields' => ' ',
'order' => ' '
)
cakephp version : 2.7.8
Looks like according to the convention, they are expecting the databse table name to be customers_addresses for the model CustomerAddress .
You have two options.
Either modify your database table name to customers_addresses.
Create a model CustomerAddress.php and write the following line within your model.
class CustomerAddress extends AppModel{
public $useTable = "customers_addresses";
}
Peace! xD

CakePHP Complex Relationship

I have the following tables:
teams(id, name)
team_users(id, team_id, user_id)
users (id, username)
projects (id, project_name, team_id)
A team hasMany users, Users hasMany teams, a project belongsTo a team.
If I call $this->User->find(); It returns the information of the user and the team's he belongs to.
What I want to do is, I would like to get a count of the projects he is associated with. Meaning:
John Doe is a member of Team X and Y. X has 2 projects and Y has 3 projects. I would like to return number of projects as 5, some sort of virtual field. Is it possible?
If you had properly set up you model relationship this query is all you need:
$this->User->virtualFields = array('total_projects' => 'COUNT(*)');
$user_projects = $this->User->find('all',array('fields' => array('total_projects', '*')));
//$user_projects["User"]["total_projects"] -> this will result to 5 base on your question above or you can debug this by: debug($user_projects) so you can see the content of the array
Use the "counterCache" option in the relation.
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#belongsto
class Project extends AppModel {
public $belongsTo = array(
'Team' => array(
'className' => 'Team',
'foreignKey' => 'team_id',
'counterCache' => true
)
);
}
You'll need to add a new field project_count to your teams table, CakePHP will do the rest.

Retrieving values from multiple tables using CakePHP model associations

I have a ProductsController in which I am retrieving Products data and need to also retrieve the Category Name. (Note: My Products table has only Category_ID in it), how can I do that using CakePHP model associations?
I have seen examples in which the ID of the main data table (in my case, Products table) is a Foreign Key in the Associated Table. However, my case slightly different in that the Category_ID (from the secondary table) is part of the Main table (Products table).
I am not able to retrieve the Category Name using CakePHP model config. Can you help?
My ProductsController is on Products table which has
ID
Prod_Name
Category_ID
....
My Categories table is like
ID
Cat_Name
In my ProductsController I want to retrieve Cat_Name for Products being retrieved.
In your Product Model, use the association:
var $belongsTo = array(
'Category' => array(
'className' => 'Category',
'foreignKey' => 'category_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
When retrieving your Products data use find method:
$this->set('variable', $this->Product->find('all'));
Once its in your View, it is an array containing all the products and its category.
Like this:
<?php
foreach($variable as $itemInTable):
echo 'Product:' . $itemInTable['Product']['Prod_Name'];
echo 'Its Category:' . $itemInTable['Category']['Cat_Name'];
endforeach;
?>
fzmaster's answer is correct. When you have a foreign key in Table A that corresponds to an id in Table B, it is said that the Model A "belongs to" Model B. At the same time, there could be an inverse relationship where Model B "has many" Model As.
The associations are fairly straightforward within that context and if you use the Cake naming conventions, you can associate the models with minimal additional code:
class Product extends AppModel{
var $belongsTo = array( 'Category' );
}
class Category extends AppModel{
var $hasMany = array( 'Product' );
}
At that point, CakePHP's Model::Find() method will automatically retrieve associated models unless you limit it with $recursive or by using the Containable behavior.

Search record in HABTM relationship - CakePHP

I have a stores and store_details table and now a store_details_stores table.
The Store model has the following:
public $hasAndBelongsToMany = array('StoreDetail');
The StoreDetail model has the following:
public $hasAndBelongsToMany = array('Store');
When I attempt the below query in the stores_controller, I receive an sql error. For some reason the store_details table is not being joined naturally. Is this expected behaviour? Do I need to join this table manually?
$this->Store->find('all', array('conditions' => array('StoreDetail.name' => 'Parking')));
This is expected behavior. You need to set up a bindModel call with your conditions, or you can create a model for your join table and query that directly.
See:
CakePHP Book - HABTM
Modelizing HABTM Join Tables
$this->Store->bindModel(array(
'hasAndBelongsToMany' => array(
'StoreDetail' => array('conditions'=>array('StoreDetail.name' => 'Parking')
))));
$this->Store->find('all');
I would recommend applying the condition to the association before you do your find, using the bindModel method.
/**
* Apply a condition to the association
*/
$this->Store->bindModel(array(
'hasAndBelongsToMany' => array(
'StoreDetail' => array('conditions' => array('StoreDetail.name'=>'Parking'))
)));
/**
* Find all Stores that have an associated StoreDetail.name of 'Parking'
*/
$this->Store->find('all');

CakePHP update extra field on HABTM join table

I have problem with updating (better updating not recreating) extra field in HABTM join table. I searched google and other sources, but struggled for 4 days now.
I have models:
class Tutorial extends AppModel {
var $hasAndBelongsToMany = array(
'TutorialCategory' => array(
'with' => 'TutorialCategoriesTutorial',
'order' => 'TutorialCategoriesTutorial.order_by ASC',
'unique' => true,
);
}
class TutorialCategory extends AppModel {
var $hasAndBelongsToMany = array(
'Tutorial' => array(
'with' => 'TutorialCategoriesTutorial',
'unique' => true,
);
}
join table tutorial_categories_tutorial have id, tutorial_id, tutorial_category_id, order_by fields.
I am trying to update order_by field like:
$order = 1;
foreach($tutorials as $i => $tutorial) {
$this->data[$i]['Tutorial']['id'] = $tutorial['Tutorial']['id];
$this->data[$i]['TutorialCategory']['id'] = $tutorial['TutorialCategory']['id];
$this->data[$i]['TutorialCategoriesTutorial']['order_by'] = $order;
++$order;
}
$this->Tutorial->bindModel(array('hasMany' => array('TutorialCategoriesTutorial')));
$saved = $this->Tutorial->saveAll($this->data);
This is deleting and crating new records in join table, but not setting order_by at all. I want to update record and set now order_by value. I tried hasMany through but no luck.
Please help and/or give advice and explanation.
Thank you!
As you have added extra data (order field) to the HABTM join model, you have actually exceeded the capabilities of a simple HABTM relationship with CakePHP. What you actually need to setup is a hasMany Through relationship.
In your case you'll basically make a "membership" model with Tutorial ID, catergory id and as much data as you want to assign to it. You will then define the relatioships as Membership belongsTo Tutorial & Category. The book probably has a better example than what I've just explained!
The main reason for this is that each "membership" record is treated as a normal record with no HABTM behaviour attached to it, so you can edit, delete and add records individually and easily.

Resources