I can't seem to find why this doesn't work. I know it's vague, but it's really all there is to say. Checking /posts I can't add the author. (Yes, I added one on /users)
Database tables:
users:
id int(11)
username varchar(50)
password varchar(50)
created datetime
modified datetime
posts:
id int(11)
title varchar(50)
body text
created datetime
modified datetime
user_id int(11)
Models
User:
class User extends AppModel {
var $name = 'User';
var $hasMany = 'Post';
}
Post:
class Post extends AppModel {
var $name = 'Post';
var $belongsTo = 'User';
}
Controllers both scaffold.
I think Your table is fine.. you have to modify your model..
like this :-
MOdels :-
USER:-
class User extends AppModel {
var $name = 'User';
var $hasMany = array('Post' => array('className' => 'Post'));
}
POST:-
class Post extends AppModel {
var $name = 'Post';
var $belongsTo = array('User' => array('className' => 'User'));
}
You can also give
var $hasMany = array(
'Post' => array(
'className' => 'Post',
'foreignKey' => 'post_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
this will work definetly..
The answer ended up not being any of the code, as what I had was already correct. (Although, Neeraj Swarnkar was also correct)
The problem was my naming of the Models. They should be named as:
post.php
and
user.php
Related
On project cakephp. I have 2 model
<?php class VisaPerson extends AppModel {
public $name = 'VisaPerson';
public $primaryKey = 'id';}?>
and
<?php class VisaProcess extends AppModel {
public $name = 'VisaProcess';
public $primaryKey = 'id';
public $belongsTo = array(
'VisaPerson' => array (
'className' => 'VisaPerson',
'foreignKey' => 'people_id'
)
);
}
?>
In controller, I writed:
if ($this->request->is('post')) {
if (!empty($this->request->data)) {
$person = $this->VisaPerson->save($this->request->data);
if (!empty($person)) {
$this->request->data['VisaProcess']['people_id'] = $this->$person->id;
$this->VisaPerson->VisaProcess->save($this->request->data);
}
}
Data saved on VisaPerson but on VisaProcess people_id not auto save.
Plese help me!
As I remember you need to add this into yours VisaPerson model:
public $hasMany = array(
'VisaProcess' => array(
'className' => 'VisaProcess',
'foreignKey' => 'people_id'
)
);
After that you only need to save VisaPerson and both tables will be filled (if $this->request->data['VisaProcess'] and $this->request->data['VisaPerson'] exists):
$this->VisaPerson->save($this->request->data);
User Model has relation:
public $hasMany = array(
'MyRecipe' => array(
'className' => 'Recipe',
)
);
I want to select all users who have recipes with ID: 1,2
How I can use that conditions in select:
$this->User->find('all', array(
'conditions' => array(
'Recipe.Id' => [1,2]
)
));
But in this example I will get also Users without recipes, how to prevent that ?
please give this relation in User model
class User extends AppModel
{
var $name = 'User';
var $belongsTo = array("Recipe");
}
and in user controller your query as
$list = $this->User->find('all',array("conditions"=>array("recipe_id IN"=> [1,2] )));
its gives output which you want..
My Category Model:
class Category extends AppModel {
public $displayField = 'name';
// public $actsAs = array('Containable');
public $hasAndBelongsToMany = array(
'Post' => array(
'className' => 'Post',
'joinTable' => 'categories_postss',
'foreignKey' => 'category_id',
'associationForeignKey' => 'post_id',
'unique' => 'keepExisting'
)
);
}
$params['contain'] = array('Post' => array(
'limit'=> 3));
pr($this->Category->find('first',$params)); exit;
It is fetching all Posts, irrespective of limit.
What I want to do:
I have this page where I ma listing all the categories and latest 5 posts related to it.
I want to limit the associated model to only 5 rows.
Any ideas?
Containable behavior is not in use
The most likely reason for this problem is that the containable behavior is not being used at all.
Compare, for the below code example:
$results = $this->Category->find('first', array(
'contain' => array(
'Post' => array(
'limit' => 3
)
)
));
Without containable behavior, it'll generate the following queries:
SELECT ... FROM `crud`.`categories` AS `Category` WHERE 1 = 1 LIMIT
SELECT ... FROM `crud`.`posts` AS `Post`
JOIN `crud`.`categories_posts` AS `CategoriesPost` ON (...)
With containable behavior, it'll generate the following queries:
SELECT ... FROM `crud`.`categories` AS `Category` WHERE 1 = 1 LIMIT
SELECT ... FROM `crud`.`posts` AS `Post`
JOIN `crud`.`categories_posts` AS `CategoriesPost` ON (...) LIMIT 3
Given this (and the code in the question) check that the AppModel has the containable behavior in $actsAs:
<?php
// app/Model/AppModel.php
class AppModel extends Model {
public $actsAs = array('Containable');
}
Limit always required?
Alternatively, or possibly in addition, you may prefer to put a limit in the association definition - To do so just define the 'limit' key:
class Category extends AppModel {
public $hasAndBelongsToMany = array(
'Post' => array(
'limit' => 100, // default to a high but usable number of results
)
);
}
the hasAndBelongsToMany relationship seems unnecessary to me. I think you only need Category hasMany Post and Post belongsTo Category relationships. Add category_id to the posts table. Make both models actAs containable.
Post Model
class Post extends AppModel {
public $actsAs = array('Containable');
var $belongsTo = array(
'Category' => array(
'className' => 'Category',
'foreignKey' => 'category_id'
),
// ... more relationships
);
Category Model
class Category extends AppModel {
public $actsAs = array('Containable');
var $hasMany = array(
'Post' => array(
'className' => 'Post',
'foreignKey' => 'category_id'
),
// ... more relationships
);
Categories Controller
class CategoriesController extends AppController {
public $paginate = array(
'Category' => array(
'contain' => array(
'Post' => array(
'limit' => 3
), // end Post
) // end Category contain
) // end Category pagination
); // end pagination
public function index() {
// for paginated results
$this->set('categories', $this->paginate());
// for find results
$this->Category->contain(array(
'Post' => array(
'limit' => 3
)
));
$this->set('categories', $this->Category->find('all'));
}
My schema is quite simple-
Each user has an id and name.
There are jobs which belong to a user. Actual schema-
CREATE TABLE `users` (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`name` varchar(20)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `jobs` (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`user_id` INT UNSIGNED ,
`type` int,
FOREIGN KEY (user_id) references users(id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
My JobsController looks like this-
<?php
class JobsController extends AppController {
public $scaffold;
public $name = 'Job';
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
)
);
}
And UsersController as-
<?php
class UsersController extends AppController {
public $scaffold;
public $name = 'User';
public $hasMany = array(
'Job' => array(
'className' => 'Job',
'foreignKey' => 'user_id'
)
);
}
Problem:
When I visit http://hostname/Jobs/add I can see a drop-down for user but its empty.
I've created few users which I can see from http://hostname/Users/
Why is drop-down empty? I am able to add jobs but when I view them, user field is shown empty.
Associations belong in the Model, not the controller.
In app/Model/User.php:
class User extends AppModel {
public $name = 'User';
public $hasMany = array('Job');
}
In app/Model/Job.php
class Job extends AppModel {
public $name = 'Job';
public $belongsTo = array('User');
}
I have the following tables for my CakePHP app that allows friendships between users:
**Users**
id
username
password
**Profiles**
id
firstname
lastname
user_id
**Friends**
id
user_id_to
user_id_from
status
So basically a user has a profile and a user can be friends with another user and this is recorded in the database table called friends with a simple status of confirmed or not using either 0 or 1 (it's an int). So friends is the join between two users.
I'm trying to list the friends for a user so for example if I get a url like:
/people/cameron/friends it will list the friends for the user Cameron.
However I'm struggling with the find statement to pass the user and find them (notice I contain the profile data) and then list friends that are related to that user. Can anyone help?
These are the Friend, User and Profile models:
class Friend extends AppModel
{
public $name = 'Friend';
public $belongsTo = array('User');
public $actsAs = array('Containable');
}
User.php
class User extends AppModel
{
public $name = 'User';
public $hasOne = 'Profile';
public $hasMany = array(
'Post',
'Answer',
'Friend' => array(
'foreignKey' => 'user_id_to'
)
);
public $belongsTo = array(
'Friend' => array(
'foreignKey' => 'user_id_from'
)
);
public $actsAs = array('Containable');
public function getFriends($username)
{
return $this->find('all',
array('conditions' => array('User.username' => $username, 'Friend.status'=>1),
'contain' => array('Friend' => array('User'))
));
}
}
Profile.php
class Profile extends AppModel
{
public $name = 'Profile';
public $belongsTo = 'User';
public $actsAs = array('Containable');
}
and this is my method for showing the friend list for a user:
public function index( $username )
{
$friends = $this->User->getFriends($username);
$this->set('friends', $this->paginate());
}
I'm currently getting this error:
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'User.user_id_from' in 'on clause'
SQL Query: SELECT `User`.`id`, `User`.`username`, `User`.`password`, `User`.`email`, `User`.`status`, `User`.`code`, `User`.`lastlogin`, `Friend`.`id`, `Friend`.`user_id_from`, `Friend`.`user_id_to`, `Friend`.`datetime`, `Friend`.`status` FROM `db52704_favorr`.`users` AS `User` LEFT JOIN `db52704_favorr`.`friends` AS `Friend` ON (`User`.`user_id_from` = `Friend`.`id`) WHERE `User`.`username` = 'cameron' AND `Friend`.`status` = 1
It looks as though the app thinks the foreign keys are in the User table rather than the friend table even though they called within the Friend association... Any ideas what the problem is?
Any time you specify foreign keys for $belongsTo, remember that the name you specify is the name of the field in the current table, not the other table.
So, for example, your $belongsTo references to 'foreignKey' => 'user_id_to' should be in the Friends model, not the Users model.
Re-read Cake's docs, as it does get confusing (even after years of Cake apps, I still need to refresh when I start a new project): http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html
Cake appears to be getting confused by those foreignKey assignments when constructing the join query.
you could try replacing each relation with the following to force the right join statement:
public $hasMany = array(
'Friend' => array(
'foreignKey' => null,
'conditions' => array('Friend.user_id_to = User.id')
)
);
public $belongsTo = array(
'Friend' => array(
'foreignKey' => null,
'conditions' => array('Friend.user_id_from = User.id')
)
);