sorry for my english and i'm new using CAKEPHP 2.3
i get a problem using model association where i can't get "joined data" ( i understand that cakephp get automatically joined data if models are set good , obviously i make it wrong )
I have 2 tables in my database:
departements (with the following columns)
-id
-name
-region_id ( region_id is a foreign key on regions(id) )
regions (with the following columns)
-id
-name
i make two models in cakePhp:
Region.php
<?php
class Region extends AppModel {
var $name = 'Region';
var $actsAs = array( 'Containable' );
public $hasMany = array(
'Departement' => array(
'className' => 'Departement',
'foreignKey' => 'region_id',
'dependent' => false
)
);
}
?>
Departement.php
<?php
class Departement extends AppModel {
var $name = 'Departement';
var $actsAs = array( 'Containable' );
public $belongsTo=array(
'Region' => array(
'className' => 'Region',
'foreignKey' => 'region_id',
'dependent' => false
)
);
}
?>
in a another controller where i need departements and regions, i tryed many thinks but after yours i need your help please !!!
i make this :
first attempt:
<?php
class SignalementsController extends AppController {
public $helpers = array('Html', 'Form');
var $name = 'Signalements';
var $uses = array('Signalements','Regions','Departements','Communes');
public $recursive = 4;
public function index() {
$departements = $this->Departements->find('all');
$this->set('departements', $departements);
}
}
who output in the index view:
array(
(int) 0 => array(
'Departements' => array(
'id' => '1',
'name' => 'AIN',
'region_id' => '82'
)
),
(int) 1 => array(
'Departements' => array(
'id' => '10',
'name' => 'AUBE',
'region_id' => '21'
)
)
...
)
but there is no region joined automatically
second attempt: i change the find models from
$regions = $this->Regions->find('all');
$this->set('regions', $regions);
who output :
array(
(int) 0 => array(
'Regions' => array(
'id' => '11',
'name' => 'ILE-DE-FRANCE'
)
), ... );
but there is no departements joined automatically
last
$fields=array('Region.id','Region.nom','Departement.id','Departement.nom');
$all= $this->Regions->Departements->find('all',$fields);
/* or all this not working as execpted
$all= $this->Departements->Regions->find('all',$fields);
$all= $this->Departements->find('all',$fields);
$all= $this->Regions->find('all',$fields);
*/
$this->set('all', $all);
i try to get the regions data inside each departemts for exemple like this
array(
(int) 0 => array(
'Departements' => array(
'id' => '1',
'nom' => 'AIN',
'region' => array( 'id' => '82', 'nom' => 'POITOU-CHARENTES')
)
),
but i get only this :
array(
(int) 0 => array(
'Departements' => array(
'id' => '1',
'nom' => 'AIN',
'region_id' => '82'
)
),
If you have any idea please leave it
thank you very much
You are using Containable behaviour in your model, so try the find with this:
$departements = $this->Departement->find('all', array('contain' => 'Region'));
Also the maximum level for recursive is 2, setting it to 4 (or 1000) has the effect of 2.
Your ID is of type varchar and should be int.
Also, here is a stripped down version of your code
Region.php
<?php
class Region extends AppModel {
var $actsAs = array( 'Containable' );
public $hasMany = array( 'Departement' );
}
?>
Departement.php
<?php
class Departement extends AppModel {
var $actsAs = array( 'Containable' );
public $belongsTo=array( 'Region' );
}
?>
<?php
class SignalementsController extends AppController {
public $helpers = array('Html', 'Form');
var $uses = array('Signalements','Regions','Departements','Communes');
public function index() {
$this->Departement->recursive = 1;
$departements = $this->Departements->find('all');
$this->set('departements', $departements);
}
}
index.ctp
<?php print_r($departements); ?>
What does it give you?
Related
I have a blog post model:
App::uses('AppModel', 'Model');
class BlogPost extends AppModel {
public $primaryKey = "ID";
public $useDbConfig = 'dev_blog';
public $useTable = 'posts';
public $hasMany = array(
'BlogComment' => array(
'foreignKey' => 'comment_post_ID',
'className' => 'BlogComment',
'order' => 'BlogComment.comment_date DESC',
'conditions' => array(
'BlogComment.comment_approved' => '1',
'BlogComment.comment_parent' => 0
)
)
);
}
And a blog comment model:
App::uses('AppModel', 'Model');
class BlogComment extends AppModel {
public $primaryKey = "comment_ID";
public $useDbConfig = 'dev_blog';
public $useTable = 'comments';
public $hasMany = array(
'Children' => array(
'className' => 'BlogComment',
'foreignKey' => 'comment_parent',
'order' => 'Children.comment_date DESC',
'conditions' => array(
'Children.comment_approved' => 1
)
)
);
}
In the controller, I set recursion on BlogPost equal to 2 and did a find:
$options = array(
'conditions' => array(
'BlogPost.ID' => $postID,
'BlogPost.post_status' => 'publish'
),
);
$post = $this->BlogPost->find('first', $options);
What this does is get the content of a particular blog post, all root comments and one level of replies to the root comments. It doesn't get a reply to a reply, though. How can I retrieve an arbitrary depth of replies?
Just don't use recursive at all. Ever.
Set it to -1 in the AppModel:
public $recursive = -1;
Then forget you even heard of it, and use CakePHP's awesome Containable Behavior to get the data you need.
Note: See the MANY other answers related to using CakePHP's Containable.
I'm trying to use find('list') method, but without success.
When I try to LIST the types of paying, just one table of database was showing correct, another is doing correct SQL but it's returning me null (even with the sql get rows).
If try to read ONE field of Tpagamento, it works
If I change the displayField of Tpagamento to 'id', it works, but the query only show the id.
Here is the scenario:
(Parcelamento and Tpagamento have the same databasefields)
View Method:
public function view($id = null) {
$this->Ordemservico->id = $id;
if (!$this->Ordemservico->exists()) {
$this->Session->setFlash('This Order does not exist..','flash_error');
$this->redirect(array('action' => 'index'));
}
//Listing all orders // THIS IS WORKING
$os = $this->Ordemservico->read(null, $id);
$this->set('os',$os);
//Listing the types of paying //THIS IS WORKING
$this->loadModel('Parcelamento');
$parcelamentos = $this->Parcelamento->find('list');
$this->set('parcelamentos',$parcelamentos);
$this->loadModel('Tpagamento'); // THIS IS NOT WORKING
$tpagamento = $this->Tpagamento->find('list');
$this->set('tpagamento ',$tpagamento );
//Read a specific type of paying, WORK!
$this->loadModel('Tpagamento'); // THIS IS WORKING
$tpagamentos = $this->Tpagamento->read(null,'5');
$this->set('tpagamentos',$tpagamentos);
}
OrdemServico Model:
class Ordemservico extends AppModel {
public $displayField = 'cliente_id';
public $belongsTo = array(
'Tpagamento' => array(
'className' => 'Tpagamento',
'foreignKey' => 'tpagamento_id',
),
'Parcelamento' => array(
'className' => 'Parcelamento',
'foreignKey' => 'parcelamento_id',
),
);
}
Tpagamento Model:
class Tpagamento extends AppModel {
public $useTable = 'tpagamentos';
public $displayField = 'nome';
public $hasMany = array(
'Ordemservico' => array(
'className' => 'Ordemservico',
'foreignKey' => 'tpagamento_id',
),
);
}
Parcelamento Model:
class Parcelamento extends AppModel {
public $displayField = 'nome';
public $hasMany = array(
'Ordemservico' => array(
'className' => 'Ordemservico',
'foreignKey' => 'parcelamento_id',
),
);
}
Generated SQL DUMP:
4 SELECT `Parcelamento`.`id`, `Parcelamento`.`nome` FROM `tereza`.`parcelamentos` AS `Parcelamento` WHERE 1 = 1 5 5 0
5 SELECT `Tpagamento`.`id`, `Tpagamento`.`nome` FROM `tereza`.`tpagamentos` AS `Tpagamento` WHERE 1 = 1 4 4 0
6 SELECT `Tpagamento`.`id`, `Tpagamento`.`nome`, `Tpagamento`.`created`, `Tpagamento`.`modified` FROM `tereza`.`tpagamentos` AS `Tpagamento` WHERE `Tpagamento`.`id` = 5 LIMIT 1 1 1 0
In the Config/database.php I setted: 'encoding' => 'utf8'
The reason to work In one table and not another is because in one table (tpagamentos) I have special characters and in another not (parcelamentos).
To show two fields in a list use the following syntax:
$this->Parcelamento->find('list', array('fields' => array('id', 'other_field_name')));
In the CakePHP Documentation they implement this as below !!
class Message extends AppModel {
public $belongsTo = array(
'Sender' => array(
'className' => 'User',
'foreignKey' => 'user_id'
),
'Recipient' => array(
'className' => 'User',
'foreignKey' => 'recipient_id'
)
);
}
and
class User extends AppModel {
public $hasMany = array(
'MessageSent' => array(
'className' => 'Message',
'foreignKey' => 'user_id'
),
'MessageReceived' => array(
'className' => 'Message',
'foreignKey' => 'recipient_id'
)
);
}
But this didn't work with me !!
and give me some errors that there's some tables in the User Model is not found !!
this will work just if I use the name of HasMany to the same name of the Model !!
After some googling searchs with fail !!
I just go to the easiest ways !!
public $hasMany = array(
'Follow_me'=>array(
'className'=>'Friend',
'foreignKey'=>'user_to' ,
) ,
'Follow_them'=>array(
'className'=>'Friend2',
'foreignKey'=>'user_from'
) );
this is the User Model
and
Class User
now the Friend Model
public $belongsTo = array(
'User'=>array(
'className'=>'User',
'foreignKey'=>'user_from' ,
) ,
);
the table of friends will be
id || user_from || user_to || created || modified
now with the easiest way !!
Create a new Model Class with the name Friend2
public $useTable = 'friends';
public $belongsTo = array(
'User'=>array(
'className'=>'User',
'foreignKey'=>'user_to' ,
) ,
);
now !!
when you fetch from the User Model the Data will be like that
array(
(int) 0 => array(
'User' => array() ,
'Follow_me' => array() ,
'Follow_them' => array() ,
'Some_Other_Relations_Goes_here' => array()
) )
Hope this will Help you All
I got this models:
class CompanyRestaurantRequest extends AppModel
{
public $name = "CompanyRestaurantRequest";
//public $actsAs = array('Containable');
public $hasMany = array(
"UserRestaurantRequestFeed" => array(
'dependent' => true
)
);
}
class UserRestaurantRequestFeed extends AppModel{
public $name = "UserRestaurantRequestFeed";
public $belongsTo = array("CompanyRestaurantRequest");
public $hasMany = array("UserRestaurantRequestFeedResponse");
}
class UserRestaurantRequestFeedResponse extends AppModel{
public $name = "UserRestaurantRequestFeedResponse";
public $belongsTo = array("UserRestaurantRequestFeed");
}
and I am trying to paginate CompanyRestaurantRequest like this:
$this->CompanyRestaurantRequest->recursive = 5;
$this->CompanyRestaurantRequestFeed->recursive = 5;
$this->paginate = array(
'limit' => 10,
'order' => array(
'CompanyRestaurantRequest.id' => 'desc'
)
);
$this->set('requests', $this->paginate("CompanyRestaurantRequest"));
The problem is that I get no CompanyRestaurantRequestFeedResponse.
I tried to attach ContainableBehavior to the CompanyRestaurantRequest model and I used contain key in paginate settings like this:
'contain' => array('CompanyRestaurantRequestFeedResponse');
Anything I try, I can not get those CompanyRestaurantRequestFeedResponses related to CompanyRestaurantRequestFeeds.
How can I make it work?
Thank you!
Intead of lines:
$this->paginate = array(
'limit' => 10,
'order' => array(
'CompanyRestaurantRequest.id' => 'desc'
)
);
At the top of the Controller where all var are declared add:
public $paginate = array(
'CompanyRestaurantRequest' => array(
'limit' => 10,
'order' => array(
'CompanyRestaurantRequest.id' => 'desc'
)
)
);
This should fix it...
I have the model AccountLicense, when I execute the method getExpiringLicenes for some reason the association I have with the parent model (AccountUser) the primary key of AccountUser is not being used, it is instead using the default primary key 'id'. I am not sure why this is happening. This is all part of a plugin.
Any help with this is greatly appreciated.
This is the exception I am getting:
Warning (512): SQL Error: 1054: Unknown column 'AccountUser.id' in 'on clause' [CORE/cake/libs/model/datasources/dbo_source.php, line 684]
This is the query that is being executed:
SELECT `AccountLicense`.`license_id`, `AccountLicense`.`user_id`,
`AccountLicense`.`board_id`, `AccountLicense`.`license_number`,
`AccountLicense`.`license_state`, `AccountLicense`.`license_designation_id`,
`AccountLicense`.`active_date`, `AccountLicense`.`expire_date`,
`AccountLicense`.`is_active`, `AccountLicense`.`is_confirmed`,
`AccountLicense`.`is_primary`, `AccountUser`.`user_id`, `AccountUser`.`user_name`,
`AccountUser`.`user_pass`, `AccountUser`.`user_status`, `AccountUser`.`user_group`,
`AccountUser`.`instance_id`, `AccountUser`.`is_logged_in`, `AccountUser`.`is_visible`,
`AccountUser`.`created_by`, `AccountUser`.`last_modified_by`,
`AccountUser`.`created_date`, `AccountUser`.`last_modified_date`
FROM `account_licenses` AS `AccountLicense`
LEFT JOIN `account_users` AS `AccountUser`
ON (`AccountLicense`.`user_id` = `AccountUser`.`id`)
WHERE `AccountLicense`.`expire_date` BETWEEN '2011-10-05' and '2011-11-04'
This is my AccountLicenses model:
<?php
class AccountLicense extends AppModel {
var $name = 'AccountLicense';
var $primaryKey = 'license_id';
var $plugin = 'AccountModule';
var $belongsTo = array(
'AccountUser' => array(
'className' => 'AccountUser',
'foreignKey' => 'user_id'
)
);
public function getExpiringLicenses($date = null)
{
if(is_null($date))
$date = date('Y-m-d',strtotime("+30 days"));
return $this->find(
'all',
array(
'conditions' => array(
$this->name . '.expire_date BETWEEN ? and ?' =>array(date('Y-m-d'),$date)
)
)
);
}
}
?>
This is my AccountUser model:
<?php
class AccountUser extends AppModel {
var $name = 'AccountUser';
var $primaryKey = 'user_id';
var $actsAs = array('Containable');
var $validate = array(
'user_name'=>array(
'rule'=>'isUnique',
'message'=>'This username has already been taken. Please try again'
),
'user_pass' => array(
'rule' => array('between', 8, 16),
'message' => 'Passwords must be between 8 and 16 characters long.')
);
var $hasMany = array(
'AccountLicense' => array(
'className' => 'AccountLicense',
'foreignKey' => 'user_id'
)
);
?>
Since is a plugin your association should have the plugin name
Example:
If your plugin name is AccountModule your association should look like
var $belongsTo = array(
'AccountUser' => array(
'className' => 'AccountModule.AccountUser',
'foreignKey' => 'user_id'
)
);
Also is not wrong, but the correct way to declare a model class inside a plugin is
<?php
class AccountLicense extends AccountModuleAppModel {
If it is in the correct place in your folder structure and correctly declared you won't need this line
var $plugin = 'AccountModule';