How to Inherit $belongsTo of AppModel in Extended Model in Cakephp - cakephp

In Cakephp,
I have used belongsTo in AppModel
class AppModel extends Model {
public $actsAs = array('Containable');
public $belongsTo = array(
'ModifiedBy' => array(
'className' => 'User',
'foreignKey' => 'common_modified_by_user_id'
)
);
}
Now I also want to apply belongs to in UserModel
class User extends AppModel {
public $belongsTo = array(
'School' => array(
'className' => 'User',
'foreignKey' => 'school_id'
)
);
}
But when i do so...it over rides the belongsTo of App model and on School data comes in the fetched array....
Please Help...

No automatic merging of associations
Other than the $actsAs and $findMethods variables, association configurations are not being merged automatically, you'll have to do that on your own.
It should be rather simple to solve, using Object::_mergeVars() in your User models constructor should do the trick:
public function __construct($id = false, $table = null, $ds = null) {
$parent = get_parent_class($this);
$this->_mergeVars(array('belongsTo'), $parent);
parent::__construct($id, $table, $ds);
}
ps. you might want to have a look at behaviors, they might be the better option for your needs.

Related

How can I do an arbitrary level of recursion in CakePHP

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.

find() method in CakePHP not working, tried searching around and not resolve.

I'm just learning cakePHP. I have a CATEGORIES table and a POSTS table. A post have one category. So there is a category_id foreign key in POSTS table.
In my Model, I have Category.php with this code.
<?php
App::uses('AppModel', 'Model');
class Category extends AppModel {
// A hasMany association will allow us to fetch a category’s posts when we fetch a Category record.
public $primaryKey = 'category_id';
public $hasOne = 'Post';
}
?>
In my Post.php I have something like this.
class Post extends AppModel {
public $hasMany = array('Photo');
public $primaryKey = 'post_id';
public $belongsTo = array('User'); // 'Category',
public $relatedImages;
public $belongsTo = 'Category';
Now in my PostController.php I have
$allCategories = $this->Category->find('list');
$this->set('allCategories', $allCategories);
The objective is to retrieve all the category from the categories table and show it in my form.
However I encountered the error of Call to a member function find() on a non-object
I'm not sure what is happening here. How can I retrieve this?
many thanks!
Use
$this->Post->Category->find('list');
As you have to goto Category table Thru posts as u r in posts controller Now currently.
In your post model try to declare the Category as below
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
)
'Category' => array(
'className' => 'Category',
'foreignKey' => 'category_id'
)
);

Limit to how deep a Many-To-Many will go with CakePHP

Is there a limit to how deep a select all will go for a many-to-may relationship? I have a design like this:
Table Survey has many Table Survey Sections. Table Survey Sections have many Questions. Table Questions have many Table Possible Responses.
If I do this for the Survey Table:
$this->loadModel('Survey');
$this->Survey->recursive = 2;
$getSurvey = $this->Survey->find('all');
It will only go as far as the Questions table but bring back the Possible Responses Table. But, if I query the Survey Sections table, it brings everything back. Is this an issue with my code or a limit to how deep a search will go?
Here is my Models:
<?php
App::uses('AppModel', 'Model');
class Survey extends AppModel {
public $validate = array(
);
public $belongsTo = array(
);
public $hasMany = array(
'surveySection' => array(
'className' => 'SurveySection',
'foreignKey' => 'surveys_id',
),
);
}
<?php
App::uses('AppModel', 'Model');
class SurveySection extends AppModel {
public $validate = array(
);
public $belongsTo = array(
);
public $hasMany = array(
'Question' => array(
'className' => 'Question',
'foreignKey' => 'survey_section_id',
),
);
}
<?php
App::uses('AppModel', 'Model');
class Question extends AppModel {
public $validate = array(
);
public $belongsTo = array(
);
public $hasMany = array(
'PossibleResponse' => array(
'className' => 'PossibleResponse',
'foreignKey' => 'questions_id',
),
);
}
<?php
App::uses('AppModel', 'Model');
class PossibleResponse extends AppModel {
public $validate = array(
);
public $belongsTo = array(
);
}
You should use $this->Survey->recursive = 3;.
As I said in the comment, the example at http://book.cakephp.org/2.0/en/models/model-attributes.html#recursive is a bit misleading because it only show an example for a specific case. In fact you can go as far as you want when fetching data.

How to join two tables using models in cakephp

I just created 2 models UsersModel and UserpicsModel and try to get both records but it is returning Error: Call to a member function find() on a non-object.
//UsersModel.php
class Users extends AppModel
{
public $hasMany = array(
'Userpics' => array(
'className' => 'Userpics'
)
);
}
//UserpicsMdoel.php
class Userpics extends AppModel
{
public $belongsTo = array(
'Users' => array(
'className' => 'Users',
'foreignKey' => 'uid'
)
);
}
//RecipesController.php
class RecipesController extends AppController {
public $uses =array('Users','Userpics');
public function view() {
$users = $this->Users->Userpics->find('all');
print('<pre>');
print_r($users);
print('<pre>');
exit;
}
}
first: you are not following cake conventions: models should be singular and not plural.
But the actual problem here is that the model files names are wrong: if you still want to use your conventions then the name for the Users model should be Users.php and not UsersModel.php
the same for Userpics
read this useful answer about how to debug this kind of error.
But if you decide to use the cake naming conventions (and I strongly suggest you to do so) consider doing the following:
//User.php (table users)
class User extends AppModel
{
....
}
//UserPic.php (table user_pics)
class UserPic extends AppModel
{
....
}
//RecipesController.php
class RecipesController extends AppController {
public $uses =array('User','UserPic');
public function view() {
$users = $this->User->UserPic->find('all');
print('<pre>');
print_r($users);
print('<pre>');
exit;
}
}
//UsersModel.php
class Users extends AppModel
{
public $hasMany = array(
'Userpics' => array(
'className' => 'Userpics',
'foreignKey' => 'uid'
)
);
}

Cakephp HABTM: Model not accessible in controller

I am trying to work with HABTM association between Profiles and Qualifications tables.
Model: Profile.php
App::uses('AppModel', 'Model');
class Profile extends AppModel {
public $hasAndBelongsToMany = array(
'Qualifications' => array(
'className' => 'Qualification',
'joinTable' => 'profile_qualifications',
'foreignKey' => 'profile_id',
'associationForeignKey' => 'qualification_id',
'unique' => 'keepExisting'
)
);
}
Model: Qualification.php
App::uses('AppModel', 'Model');
class Qualification extends AppModel {
public $hasAndBelongsToMany = array(
'Profile' => array(
'className' => 'Profile',
'joinTable' => 'profile_qualifications',
'foreignKey' => 'qualification_id',
'associationForeignKey' => 'profile_id',
'unique' => 'keepExisting',
)
);
}
Controller: ProfilesController.php
App::uses('AppController', 'Controller');
class ProfilesController extends AppController {
public function add() {
$qualifications = $this->Qualification->find('list'); /* Attempt 1 */
$qualifications = $this->Profile->Qualification->find('list'); /* Attempt 2 */
$qualifications = $this->Profile->ProfileQualification->Qualification->find('list'); /* Attempt 3 */
}
}
All three attempts mentioned as comment have given me an error saying:
Error: Call to a member function find() on a non-object
File: ~/app/Controller/ProfilesController.php
Line: xxx
I want to know how can I generate a list of all entries in Qualifications table ?
Moreover, what is the mistake in my code right now ?
In your Profile Model, the alias of your HABTM relation with Qualification is "Qualifications", so inside the controller you have to use : $qualifications = $this->Profile->Qualifications->find('list'); or remove the plural from the model.
To prevent these kind of mistakes and save your time, it's really useful to use automatic code generation with the cake bake console or an online CakePHP baking tool.

Resources