this is my situation, I have a Post model that can belong to multiple Categories. This I figured out how to do:
class Post extends AppModel
{
var $hasAndBelongsToMany = array('Category');
}
And the Category model:
class Category extends AppModel
{
var $hasAndBelongsToMany = array ('Post');
}
Now, this all works fine and all that. But I just cannot figure out how to search for posts that belong to a certain category, for example "News" with the id of 1 to use in:
class CategoriesController extends AppController {
function view ($id = 0) {
// doesnt work
$this->Category->Video->find ('all', array('conditions' => array('category_id' => $id));
}
}
I've been trying to find an answer on Google and the CookBook but have found nothing yet. Does anyone know how this can be achieved?
Thank you.
You are performing a find on Video model, when you showed association on Category and Post models, not Video. Assuming this is a typo error:
If you want to search, as you stated, posts that are of "News" category do in posts_controller.php:
$this->Post->Category->find('all', array('conditions'=>array('Category.name'=>'News')) );
Or in the categories_controller.php
$this->Category->find('all', array('conditions'=>array('Category.name'=>'News')) );
Your easiest bet would be to search the Category itself, and allow the recursive level to also return associated Posts (or Videos, or whatever you're doing):
//in the category controller
$this->Category->find('all', array('conditions'=>array('Category.id'=>$id));
There are many options for searching against HABTM data, but the above is the easiest.
Here's the page in the CakePHP book that describes different ways to query against a HABTM relationship:
http://book.cakephp.org/1.3/view/1044/hasAndBelongsToMany-HABTM
You can do the following which should work:
$this->Category->bindModel(array(
'hasOne' => array(
'CategoriesVideo'
),
));
return $this->Video->find('all', array(
'conditions' => array(
'CategoriesVideo.category_id' => $id,
),
),
));
EDIT: Sorry, was looking at the wrong code. This should work.
Related
I have search working fine for the parent model, but I have no idea how to get child models/tables included in the Select portion of the query.
Using Cake 2.3.8
This article (how to use cakedc/search plugin for searching across 3 different tables with 1 search bar?) seems like the closest answer, but I'm new to cake and don't quite understand #mark's concise answer.
Any help would be much appreciated,
Thanks!
Let me shorten the example from the readme.md for you, it should become obvious:
class Article extends AppModel {
public $actsAs = array('Search.Searchable');
public $belongsTo = array('User');
public $filterArgs = array(
'title' => array('type' => 'like'),
'username' => array('type' => 'like', 'field' => array(
'User.username', 'UserInfo.first_name')),
);
Notice the Model.field notation for the username filter.
I have a consultant table that has a foreign key 'specialty_id' which is linked to a 'specilaties' table.
class Consultant extends AppModel {
public $belongsTo = array(
'Specialty' => array(
'className' => 'Specialty',
'conditions' => array('Specialty.active' => 1)
)
);
}
class Specialty extends AppModel {
public $hasOne = 'Consultant';
}
I think this is right, however, i am unable to get a list of specialties from the consultant controller
("Call to a member function find() on a non-object ")
$this->set('specialties', $this->Specialty->find('all'));
Where abouts am i going wrong?
Thank you
Remember you are in the controller, not in the model. Try this:
$this->set('specialties', $this->Consultant->Specialty->find('all'));
If you are using Model in other controller then, first load that model and then run query:
$this->loadModel('Specialty');
I got a Table Users and a Table Groups. Every group has one GroupLeader.
So the field i use in is groupLeader ($hasOne) which contains a foreign key of users.
I cant manage to get that relation. So my question is, how to define a relation on a field with a diffent name.
thanks for a hint.
endo
You model should looks:
class Group extends AppModel
{
public $name = 'Group';
public $belongsTo = array('GroupLeader' => array(
'className' => 'User',
'foreignKey' => 'groupLeader'
)
);
}
Try with the above code. And ask if it is not worked for you.
I have this model and controller and it returns fine if it is a hasOne relationship but now DishCategory hasMany dishes. When I change the code below to hasMany it gives me an error saying Dish.id is not a known column while if it is a hasOne it works fine. How can I make it so that it returns all the Dish.id's that have id=1? (still using the join).
class DishCategory extends AppModel{
public $hasOne = array(
'Dish' => array(
'className' => 'Dish',
'foreignKey' => 'dish_category_id'
)
);
}
class DishCategoriesController extends AppController {
function get_categories($id)
{
// find category with a dish of $id
$this->set('dishes', $this->DishCategory->find('all', array(
'conditions' => array(
'Dish.id' => $id
)
)));
// set master layout
$this->layout = 'master_layout';
}
}
hasOne relations can be joined into the primary SQL query. hasMany relations cannot and need to be queried in a separate query. The conditions you specify for the query only apply to the primary query, all separate relational queries are build just based on the ids retrieved in the primary query. Set debug to 2 and have a good look at the query log to see what I mean.
To find the category of a dish, fetch the dish and look at its related category record:
$dish = $this->Dish->find('first', array('conditions' => array('Dish.id' => $id)));
echo $dish['DishCategory']['name'];
Since I take it that a dish belongsTo one category, your query "find all categories which have a dish with id x" makes little sense; there should only be one anyway.
I've got the field country_id in one of my models and instead of creating a countries table which contains a list of countries that doesn't change, what's the best approach to this?
I'm thinking about using a model without a database table but I don't know how to implement this.
Please help. Thanks in advance!
you can totaly use the no table syntax:
class ModelWithoutTable extends AppModel
{
var $useTable = false;
}
to have this Country Model tableless, but you need to mock a data source (i.e. XML,YAML,PHP Array and etc) for the countries data.
Hope this helps.
I would suggest using ArraySource from the community-maintained CakePHP Datasources plugin:
CakePHP 1.3.x - see master branch
CakePHP 2.x - see 2.0 branch
Download the entire plugin and extract the contents to app/plugins/datasources.
Define a connection to the datasource in app/config/database.php:
public $array = array('datasource' => 'Datasources.array');
This should allow you to emulate a table by defining records in your model:
class Country extends AppModel {
public $useDbConfig = 'array';
public $records = array(
array('id' => 1, 'name' => 'Test record')
);
}
As alternative, if there's no other data attached to the country besides, basically, an id of what country it is, you can probably keep it within the same model without association. Something along the lines of:
class MyModel extends AppModel {
public static $countries = array(
'Africa', 'America', ..., 'Zululand'
);
public $validate = array(
'country' => array(
'rule' => array('inList', self::$countries),
...
)
)
}