Cakephp: Model can't be loaded in controller - cakephp-2.0

I have a model called "Specialite" and i want to load it in MissionController action but it dosen't work.
I put this code $this->loadModel('Specialite'); inside the action and when i make a debug: debug($this->Specialite->find('all')); no data is returned !!
While the table specialites in DB contains data..
This is the Model class of Specialite :
<?php
App::uses('AppModel', 'Model');
/**
* Specialite Model
*
* #property Filiale $Filiale
* #property Formation $Formation
* #property Laboratoire $Laboratoire
*/
class Specialite extends AppModel {
/**
* Validation rules
*
* #var array
*/
public $displayField = 'nom';
public $validate = array(
'nom' => array(
'notempty' => array(
'rule' => array('notempty'),
//'message' => 'Your custom message here',
//'allowEmpty' => false,
//'required' => false,
//'last' => false, // Stop validation after this rule
//'on' => 'create', // Limit validation to 'create' or 'update' operations
),
),
);
//The Associations below have been created with all possible keys, those that are not needed can be removed
/**
* hasMany associations
*
* #var array
*/
public $hasMany = array(
'Filiale' => array(
'className' => 'Filiale',
'foreignKey' => 'specialite_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
'Formation' => array(
'className' => 'Formation',
'foreignKey' => 'specialite_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
'Laboratoire' => array(
'className' => 'Laboratoire',
'foreignKey' => 'specialite_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
'Client' => array(
'className' => 'Client',
'foreignKey' => 'client_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
}
When I load other Models the find() works pretty fine !! Only and Only with "Specialite" model it refuses to work ! :'(
I really need help ! Thanks in advance !

Please check debug mode in Config/core.php if set 0 than change it to 1 like:-
Configure::write('debug', 1);

Related

CakePHP adding to multiple tables from one view

can someone provide an explanation for me?
I've got a database where I'm trying to update 4 tables from one page, Organizations, OrganizationsDetails, Account, AccountRoles. The add view itself would contain fields for the Account and the Organization. When I call the OrganizationsController add function, I want to then call add on AccountController, AccountRolesController (set Account as an administrator role), and OrganizationDetailsController (set that Account as the administrator for that specific Organization).
Should I be using components for this? When I call add() on the Organizations, I always intend to perform these steps - never solely create the Organizations entry below. Should I be doing this directly in that function or some other method?
Let me know if I need to explain more, thanks!
EDIT: Added the four models below:
Organization
class Organization extends AppModel {
public $hasMany = array(
'Account' => array(
'className' => 'Account',
'foreignKey' => 'organization_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
public $hasOne = array(
'OrganizationDetail' => array(
'className' => 'OrganizationDetail',
'foreignKey' => 'organization_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
OrganizationDetail
class OrganizationDetail extends AppModel {
public $belongsTo = array(
'Organization' => array(
'className' => 'Organization',
'foreignKey' => 'organization_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Account' => array(
'className' => 'Account',
'foreignKey' => 'account_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
AccountRole
class AccountRole extends AppModel {
public $belongsTo = array(
'Account' => array(
'className' => 'Account',
'foreignKey' => 'account_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Role' => array(
'className' => 'Role',
'foreignKey' => 'role_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
Account
class Account extends AppModel {
public $belongsTo = array(
'Organization' => array(
'className' => 'Organization',
'foreignKey' => 'organization_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
public $hasOne = array(
'OrganizationDetail' => array(
'className' => 'OrganizationDetail',
'foreignKey' => 'account_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
public $hasMany = array(
'AccountRole' => array(
'className' => 'AccountRole',
'foreignKey' => 'account_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
You've got wrong the whole MVC idea. Controllers should not call methods in other controllers (or at least not in this scenario).
The right approach would be to set up OrganizationsController->add() so that it saves all the data by independent calls to each Model->save($data), or by using
Organization->saveAssociated($data,array('deep' => true))
Your form fields need to be named properly for this to work. For example:
echo $this->Form->create('Organization', array('action' => 'add'));
echo $this->Form->input('Organization.name'));
echo $this->Form->input('Account.0.name', array('label' => 'Account name'));
echo $this->Form->input('OrganizationDetail.details', array('label' => 'Org. Details'));
echo $this->Form->input('Account.0.AccountRole.id', array('label' => 'Account Role'));
echo $this->Form->end('Add');
However, you may get into trouble if you try to go too many levels deep. If you find yourself in this situation, it's probably because you data model is flawed.
This is what your data model currently looks like:
This is what I believe it should look like:
It is critical to have your data model right before you start coding. It can save you many headaches!

How deep is the cakephp delete cascade

I have three tables Book->pages->assets when I delete a book I delete the pages associated with it. I also want to delete the assets associated with page when I delete a book.
How deep does book delete cascade go? My book and pages delete but not assets. If I know cakephp should delete the assets also then I know it is just my setup.
Book Model
public $hasMany = array(
'Page' => array(
'className' => 'Page',
'foreignKey' => 'book_id',
'dependent' => true,
'conditions' => '',
'fields' => '',
'order' => 'order',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
Page model
public $hasMany = array(
'Asset' => array(
'className' => 'Asset',
'foreignKey' => 'page_id',
'dependent' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
);
}
Book Controller
$this->Book->delete($id, true)

Delete Multiple Selected Records from checkbox in a relation

I have two Model. One is user and onother is UserProfile and in created their tables users and user_profiles respectivly. I want when i delete user data thenrelated UserProfile should also automatically deleted. I created hasone and belongs to relation. One more thing i am deleting data using checkbox with delete button so i could able to delete multiple record at once.
User.php
public $hasOne = array(
'UserProfile' => array(
'className' => 'UserProfile',
'foreignKey' => 'user_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
);
UserProfile.php
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
);
In UsersController i have a deleteSelected function
UsersController.php
public function deleteSelected()
{
foreach($this->data['User'] as $key => $value)
{
if($value != 0)
{
$this->User->delete($value);
}
}
$this->redirect($this->referer());
}
finaaly i am getting an Error: Table groups_users for model GroupsUser was not found in datasource default. Please tell whats wrong in my code. Thanks.
set dependent to true
public $hasOne = array(
'UserProfile' => array(
'className' => 'UserProfile',
'foreignKey' => 'user_id',
'dependent' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
),
);

After upgrade 1.3 -> 2.4: find() doesn't join associated models

i recently upgraded my 1.3-app to 2.4 with https://github.com/dereuromark/upgrade
But now some usages of $this->Model->find() doesn't work. Especially the joins to the associated models/tables.Resulting in "Unknown column 'Bill.customer_id' in where clause".
My setup:
Tables and Associations: http://i.stack.imgur.com/bjOIz.png (Image)
Models:
App::uses('AppModel', 'Model');
class Customer extends AppModel {
public $actsAs = array('Logable', 'Containable');
public $hasMany = array(
'Bill' => array(
'className' => 'Bill',
'foreignKey' => 'customer_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)...
-----------------------------------------------------------------
App::uses('AppModel', 'Model');
class Bill extends AppModel {
public $actsAs = array('Containable', 'Logable', 'Lockable');
public $belongsTo = array(
'Customer' => array(
'className' => 'Customer',
'foreignKey' => 'customer_id',
'conditions' => '',
'fields' => '',
'order' => ''
)...
public $hasAndBelongsToMany = array(
'Stage' => array(
'className' => 'Stage',
'joinTable' => 'bills_stages',
'foreignKey' => 'bill_id',
'associationForeignKey' => 'stage_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)...
--------------------------------------------------------------
App::uses('AppModel', 'Model');
class BillsStage extends AppModel {
public $actsAs = array('Containable', 'Logable', 'Lockable');
public $belongsTo = array(
'Bill' => array(
'className' => 'Bill',
'foreignKey' => 'bill_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Stage' => array(
'className' => 'Stage',
'foreignKey' => 'stage_id',
'conditions' => '',
'fields' => '',
'order' => ''
)...
--------------------------------------------------------
App::uses('AppModel', 'Model');
class Stage extends AppModel {
public $displayField = 'name';
public $actsAs = array('Tree', 'Containable', 'Logable');
public $hasMany = array(
'Bill' => array(
'className' => 'Bill',
'foreignKey' => 'stage_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)...
public $hasAndBelongsToMany = array(
'Bill' => array(
'className' => 'Bill',
'joinTable' => 'bills_stages',
'foreignKey' => 'stage_id',
'associationForeignKey' => 'bill_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)...
In 1.3 the joins are working. In 2.4 only 1-dimensional sql query.
Any idea?
--edit--
$billsStages = $this->Customer->Bill->BillsStage->find('all', array(
'conditions' => array(
'Bill.customer_id' => $this->Customer->id,
'Stage.id' => array_keys($vk_stages)
),
'order' => 'BillsStage.created DESC'
));
Try a join (example taken out from the docs)
$options['joins'] = array(
array('table' => 'bills',
'alias' => 'Bill',
'type' => 'LEFT',
'conditions' => array(
'Bill.customer_id' => $this->Customer->id,
)
),
array('table' => 'stages',
'alias' => 'Stage',
'type' => 'LEFT',
'conditions' => array(
'Stage.id' => array_keys($vk_stages)
)
)
);
$options['conditions'] = array();
$items= $this->Customer->Bill->BillsStage->find('all', $options);
(adjust to your case).
According to this answer, a contain for conditions on the secondary model is not possible, since contain makes a different query. So use joins if you want to apply conditions on secondary models, or create a simple function in your model that does two separate queries and creates a macro array that returns the mixed results if you want to use contain.

How do I get the releated object names?

I have a problem that I've been trying to resolve for hours. Let's say that I have a book model, an author model and a country model.
When viewing a book entry, at the bottom of the page, there are the related objects. In this case, authors.
The page shows me the related data for the author, the author's name and other details display fine. The country, however, is displayed as country_id.
Is there a way that I can change that to country name?
UPDATE:
I have these three tables:
Book HMBM Authors H Country
A book may be written by many authors (for anthologies)
An author may write many books
An author may reside in a country
A country may host may authors.
Book:
public $hasAndBelongsToMany = array(
'Author' => array(
'className' => 'Author',
'joinTable' => 'author_books',
'foreignKey' => 'book_id',
'associationForeignKey' => 'author_id',
'unique' => '',
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'deleteQuery' => '',
'insertQuery' => ''
)
);
Author:
public $hasMany = array(
'Book' => array(
'className' => 'Book',
'foreignKey' => 'book_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
public $belongsTo = array(
'Country' => array(
'className' => 'Country',
'foreignKey' => 'country_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
Country:
public $hasMany = array(
'Author' => array(
'className' => 'Author',
'foreignKey' => 'country_id',
'dependent' => false,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'exclusive' => '',
'finderQuery' => '',
'counterQuery' => ''
)
If a book has an author, and an author has a country, the data you require is outside the ORM's mechanism to avoid recursive calls to the database. Call $this->Book->recursive = 2in your controller method to increase the recursion limit.

Resources