I have an article model with Tags and MenuItems associated with it.
I want to show Articles with a certain MenuItem id.
When a preform a find operation on the model it return an (Unknown column 'MenuItem.id' in 'field list') error.
I have know idea what i'm doing wrong.
Article Model:
public $hasAndBelongsToMany = array(
'Tag' => array(
'className' => 'Tag',
'joinTable' => 'articles_tags',
'foreignKey' => 'article_id',
'associationForeignKey' => 'tag_id'
),
'MenuItem' => array(
'className' => 'MenuItem',
'joinTable' => 'menu_items_articles',
'foreignKey' => 'article_id',
'associationForeignKey' => 'menu_item_id',
'unique' => 'keepExisting'
)
);
Article Controller:
$allArticles = $this->Article->find('all',
array(
'fields' => array('MenuItem.id','Article.id','Article.name'),
'conditions'=>array('Article.content_type'=>'blog','MenuItem.id'=>7),
'recursive'=>2
)
);
debug($allArticles);
Try this :
$this->Article->Behaviors->attach('Containable');
$allArticles = $this->Article->find('all',
array('contain' => 'MenuItem.id'),
'fields' => array('Article.id','Article.name'),
'conditions'=>array('Article.id'=>4),
)
);
debug($allArticles);
Related
My Cakephp Application Has the following models with relations ships
class Category extends AppModel {
public $hasAndBelongsToMany = array(
'Product' => array(
'className' => 'Product',
'joinTable' => 'products_categories',
'foreignKey' => 'category_id',
'associationForeignKey' => 'product_id',
'unique' => 'keepExisting',
),
);
}
class Product extends AppModel {
public $primaryKey = 'id';
public $hasMany = array(
'ProductSwatch' => array(
'className' => 'ProductSwatch',
'foreignKey' => 'product_id',
'dependent' => true
),
'ProductDimension' => array(
'className' => 'ProductDimension',
'foreignKey' => 'product_id',
'dependent' => true
),
'ProductCare' => array(
'className' => 'ProductCare',
'foreignKey' => 'product_id',
'dependent' => true
),
'ProductDimension' => array(
'className' => 'ProductDimension',
'foreignKey' => 'product_id',
'dependent' => false,
),
'ProductCare' => array(
'className' => 'ProductCare',
'foreignKey' => 'product_id',
'dependent' => false,
),
'Review' => array(
'className' => 'Review',
'foreignKey' => 'product_id',
'dependent' => true,
)
);
}
When i am finding all the Category elements only Product Model contents are coming is there any way to get the Products associations(ProductDimension, ProductSwatches, etc) when we fetch the Categories model?
By default CakePHP 2 recursion level is 1st level association only.
You can use recursive option of find (or model property) to fetch deep associations.
For more information about model recursive property, see: http://book.cakephp.org/2.0/en/models/model-attributes.html#recursive
For example:
$this->Category->find('all', array(
'recursive' => 2,
'conditions' => array(), // Your conditions, etc.
));
Another (and better way) is using Containable behaviour.
add
public $actsAs = array('Containable');
to your model(s) to enable Containable behaviour. Then you can use:
$this->Category->find('all', array(
'contain' => array(
'Product' => array(
'ProductSwatch',
'ProductDimension',
'ProductCare',
'Review',
),
),
'conditions' => array(), // Your conditions, etc.
));
to fetch deeper associations.
For more information about Containable behaviour and deeper associations, see http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html#containing-deeper-associations
I'm trying to do this with last 2.x CakePHP version
http://i.stack.imgur.com/IylLu.png
Without education_id in projects_students table works perfectly. But doesn't work with education_id.
this is my implementation with education_id:
ProjectsStudent.php
class ProjectsStudent extends AppModel {
public $belongsTo = array(
'Project' => array(
'className' => 'Project',
'foreignKey' => 'project_id'
),
'Student' => array(
'className' => 'Student',
'foreignKey' => 'student_id'
)
);
Student.php
public $hasMany = array('ProjectsStudent');
public $hasAndBelongsToMany = array(
'Education' => array(
'className' => 'Student',
'joinTable' => 'projects_students',
'foreignKey' => 'student_id',
'associationForeignKey' => 'project_id',
),
);
Project.php
public $belongsTo = 'Status';
public $hasMany = array(
'Doc' => array(
'className' => 'Doc',
'joinTable' => 'docs',
'foreignKey' => 'project_id',
),
'History' => array(
'className' => 'History',
'joinTable' => 'history',
'foreignKey' => 'project_id',
),
'ProjectsStudent'
);
public $hasAndBelongsToMany = array(
'Student' => array(
'className' => 'Student',
'joinTable' => 'projects_students',
'foreignKey' => 'project_id',
'associationForeignKey' => 'student_id',
),
'Professor' => array(
'className' => 'Professor',
'joinTable' => 'projects_professors',
'foreignKey' => 'project_id',
'associationForeignKey' => 'professor_id',
),
'Education' => array(
'className' => 'Education',
'joinTable' => 'projects_educations',
'foreignKey' => 'project_id',
'associationForeignKey' => 'education_id',
),
);
ProjectsController.php
$data = array(
'Project' => array(
'id' => $id,
'status_id' => 5,
'Student' => array($this->Auth->user('id'))),
'History' => array(
array(
'action' => 'update -> status 5',
'student_id' => $this->Auth->user('id'),
)
),
'ProjectsStudent' => array(array(
'education_id' => "5"))
);
$this->Project->saveAll($data, array('deep' => true))
Output error:
Error: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '109' for key 'PRIMARY'
SQL Query: INSERT INTO tfg.projects_students (project_id, education_id) VALUES (109, 5)
I think CakePHP is trying 2 inserts, with (project_id, student_id) and with (project_id, education_id)
I want just one input like INSERT INTO tfg.projects_students (project_id,student_id,education_id) VALUES (109, 1, 5)
Thanks in advance, sorry for my english.
---SOLUTION---
$data = array(
'Project' => array(
'id' => $id,
'status_id' => 5,
'Student' => array($this->Auth->user('id'))),
'History' => array(
array(
'action' => 'update -> status 5',
'student_id' => $this->Auth->user('id'),
)
),
);
$this->Project->saveAll($data, array('deep' => true));
$this->Project->ProjectsStudent->updateAll(
array('education_id' => $this->Auth->user('education')),
array('project_id' => $this->Project->id));
You appear to have setup the projects_students table to use project_id as the primary key. The primary key needs to be unique whereas the project_id foreign key is likely to be duplicated (as appears to be happening for you). The join table should be at least:-
id (int)
project_id (int)
student_id (int)
Where id is the primary key (with auto increment enabled).
Given the following:
Content Model
public $hasAndBelongsToMany = array(
'Tag' => array(
'className' => 'Tag',
'joinTable' => 'contents_tags',
'foreignKey' => 'content_id',
'associationForeignKey' => 'tag_id',
'unique' => 'keepExisting',
)
);
Tag Model
public $hasAndBelongsToMany = array(
'Content' => array(
'className' => 'Content',
'joinTable' => 'contents_tags',
'foreignKey' => 'tag_id',
'associationForeignKey' => 'content_id',
'unique' => 'keepExisting',
)
);
Book Model
public $belongsTo = array(
'Content' => array(
'className' => 'Content',
'foreignKey' => 'content_id',
),
);
The Book model has a content_id. How can I ( if at all possible ) relate the Book Model to the Tag Model?
If you add a HasOne or HasMany relationship from the Content to the Book Model then Tag and Book are indirectly related via Content. If you want to use a find-call on one of them and get the other as associated data then all you have to do is set the recursive variable high. Does that make sense? Also then you can do stuff like $this->Book->Content->Tag or $this->Tag->Content->Book in their respective controllers.
I have a HABTM relationship and I'd like to get nested data for a categories table from a product table something like this product array:
array(
(int) 0 => array(
'id' => (int) 1,
'name' => 'a',
'categories' => array(
(int) 0 => array(
'id' => (int) 1
),
(int) 1 => array(
'id' => (int) 2
)
)
),
(int) 1 => array(
'id' => (int) 2,
'name' => 'b',
'categories' => array(
(int) 0 => array(
'id' => (int) 1
)
)
)
)
Is this possible with cake?
EDIT: I will try to explain further what I want to do.
Please bear with me, I am new to cake and am having trouble getting to grips it.
I have a 'product' table:
public $hasAndBelongsToMany = array(
'Category' => array(
'className' => 'Category',
'joinTable' => 'categories_sculptures',
'foreignKey' => 'sculpture_id',
'associationForeignKey' => 'category_id',
'unique' => 'keepExisting'
)
)
and a category table:
public $hasAndBelongsToMany = array(
'Sculpture' => array(
'className' => 'Sculpture',
'joinTable' => 'categories_sculptures',
'foreignKey' => 'category_id',
'associationForeignKey' => 'sculpture_id',
'unique' => 'keepExisting'
)
);
and a category products table:
public $belongsTo = array(
'Category' => array(
'className' => 'Category',
'foreignKey' => 'category_id',
'conditions' => '',
'fields' => '',
'order' => ''
),
'Sculpture' => array(
'className' => 'Sculpture',
'foreignKey' => 'sculpture_id',
'conditions' => '',
'fields' => '',
'order' => ''
)
);
I would like to build a view table of the sculptures and also show in each row which categories each sculpture is in (which could be more than one). As I am new to cake I don't know how I would go about this. If I was just querying mysql I could get this information with a group_concat or a nested select, or inefficiently by looping through first array and querying the category_sculpture table by sculpture key and adding the results to the first array. But I would like to know the best way to get this result the cake way.
I have found the answer to my needs:
$this->Sculpture->recursive = 1;
I have the following relationships set up:
Teacher:
var $hasAndBelongsToMany = array(
'Classroom' => array(
'className' => 'Classroom',
'joinTable' => 'classrooms_teachers',
'foreignKey' => 'teacher_id',
'associationForeignKey' => 'classroom_id',
'unique' => true,
)
);
Classroom:
var $hasAndBelongsToMany = array(
'Teacher' => array(
'className' => 'Teacher',
'joinTable' => 'classrooms_teachers',
'foreignKey' => 'classroom_id',
'associationForeignKey' => 'teacher_id',
'unique' => true,
)
);
var $hasMany = array(
'Student' => array(
'className' => 'Student',
'foreignKey' => 'classroom_id',
'dependent' => false,
),
);
Student:
var $belongsTo = array(
'Classroom' => array(
'className' => 'Classroom',
'foreignKey' => 'classroom_id',
),
);
I am trying to create a dashboard for the teachers, where all students associated with the teacher through the classroom are displayed.
I am using the following find operation:
$students = $this->Teacher->Classroom->find('all', array(
'conditions' => array('Classroom.teacher_id' => $this->Access->getTeacherId()),
));
However, I am getting an error: Unknown column 'Classroom.teacher_id' in 'where clause'
I must be doing something wrong because cake is not doing the associations.
Any ideas?
This is the correct way of achieving this:
$this->Teacher->bindModel(array('hasOne' => array('ClassroomsTeachers')));
$students = $this->Teacher->find('all', array(
'conditions' => array('ClassroomsTeachers.teacher_id' => $this->Access->getTeacherId()),
'recursive' => 2
));
I hope it helps someone!
That's not the best way. Just use containable and find('first'), you don't need find all:
$students = $this->Teacher->find('first', array(
'conditions' => array('Teacher.id' => $this->Access->getTeacherId()),
'contain' => array('Classroom'=>array('Student'))
));
That will get you all the classrooms associated with the teacher, and all students in those classrooms.
I made a behavior to solve the HABTM problem.
Posted my answer here:
HABTM Find with CakePHP 2.0