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.
Related
I'll be straightforward: I want to manage multiple (Link) trees according to their respective menu_id. As long as there is only one tree: no problem. Things get messed up when I start another tree in my link model with a different menu id.
I whish to be able to add, edit, remove, moveUp or moveDown while preserving the scope (menu_id).
This part of the documentation is unclear to me :
http://api.cakephp.org/2.5/source-class-TreeBehavior.html#41-49
Here my Link model.
<?php
App::uses('AppModel', 'Model');
class Link extends AppModel {
public $name = 'Link';
public $displayField = 'title';
public $actsAs = array('Tree' => array(
'parent' => 'parent_id',
'left' => 'lft',
'right' => 'rght',
'scope' => "WHAT-SHOULD-I-PLACE-HERE??",
));
public $belongsTo = array(
'Menu' => array(
'className' => 'Menu',
'foreignKey' => 'menu_id',
)
);
}
And my Menu model.
<?php
App::uses('AppModel', 'Model');
class Menu extends AppModel {
public $displayField = 'title';
public $hasMany = array(
'Link' => array(
'className' => 'Link',
'foreignKey' => 'menu_id',
'dependent' => false,
)
);
}
Thanks to BadHorsie I finally came up to understand that is it pointless to declare the scope in the model's behavior settings.
Instead you (currently I) need to attach the behavior on the fly, with the required scope before any action (add, edit, move up, move down etc) for this to work.
Now, what I need to make sure is that a link always has a menu_id.
And when someone edits a link, the parent_id dropdown must be repopulated according to the menu_id dropdown (javascript needed here and more validation rules in the model to ensure integrity).
The solution was to create a new function in the Link model. it's goal is to preserve the scope when any modification is made to the tree (move up, move down, remove from tree, delete, etc).
public function preserveScope($menuId) {
$this->Behaviors->attach('Tree', array(
'scope' => array(
'Link.menu_id' => $menuId
),
));
return true;
}
The scope is basically a SQL condition (in Cake format).
So you probably need to set the scope to the menu ID that you want.
'scope' => array(
'Link.menu_id' => 5
);
However, you probably don't know which ID yet when trying to set up the array on the class definition, so you might have to do it on the fly.
$this->Link->Behaviors->attach('Tree', array(
'scope' => array(
'Link.menu_id' => $id // You need to decide how to get this ID
),
));
I don't know when you would need to do this though. It's up to you to decide when to attach the behavior.
Edit: If the moveUp/moveDown methods are not working correctly, perhaps the scope field you are using is not correct?
I am using scaffolding in cakePHP. The default view shows me maximum of 20 records.
How can I increase the limit of records to show?
thanks!
Scaffolding is nice to test your relation, I think you use this :
class CustomNameController extends AppController {
public $scaffold;
}
But If you find yourself really wanting to customize your logic and your views, it’s time to pull your scaffolding down in order to write some code. CakePHP’s bake console is a great because it generates all the code that would produce the same result as the most current scaffold.
Look at : http://book.cakephp.org/2.0/en/console-and-shells/code-generation-with-bake.html.
After that you have to put on your new "CustomNameController":
public $components = array('Paginator');
public $paginate = array(
'limit' => 25, // or more if you want !
);
Other solutions is to change:
public $settings = array(
'page' => 1,
'limit' => 20,
'maxLimit' => 100,
'paramType' => 'named'
);
on PaginatorComponent.php or extend Scaffold.php directly on the CakePHP Lib.
I try to code a order system and it is my first cake project.
i have a order, a user and a useraddress.
//Order model
public $belongsTo = array(
'User' => array(
'className' => 'User'
));
//User model
public $hasOne = array(
'Useradr' => array(
'className' => 'Useradr',
'foreignKey' => 'user_id',
'order' => ''
)
);
//maybe not necessary Useradr model
public $belongsTo = 'User';
Now i want to access the useraddress while i add/edit a voucher.
I can access the User in the voucher edit view:
echo $this->Form->input('User.email',array(
'label' => 'Email',
));
But not the Useraddress. What iam doing wrong ?
Thank you very much!
Julius
You have to use the correct model prefix.
echo $this->Form->input('Useradr.some_field',array(
'label' => 'Some Field',
));
I suggest you to do the blog tutorial instead of starting blindly coding. Also reading about the conventions is a good idea.
Further Useradr is a pretty bad name, better would be UserAddress. Abbreviations suck for multiple reason. First they're hard to guess if you don't know what they mean and the inflector very likey does not like them either and might screw up the singular/plural cases. Read Clean Code, very nice book about how to write clean code.
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.
I want to create a binding from one model to my User model on the fly so that the JOIN is not called every time that I perform a find on that model. I am using the binding to perform a HABTM save. However, when I use the bindModel function, the HABTM data is not saved in the database.
What makes this odd is that if I move my binding to the User model, then the save works perfectly. I don't see any indication in the documentation that the save behavior would be different when the association is made in the model versus the bindModel function (though, I may have missed it if there is any).
Here is my bindModel code in my controller:
$this->User->bindModel(
array(
'hasAndBelongsToMany' => array(
'Othermodel' => array(
'className' => 'Othermodel',
'joinTable' => 'othermodels_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'othermodel_id',
'unique' => true,
)
)
)
);
if($res = $this->User->save($data)){
return true;
}
And this is my user model.
class User extends AppModel {
public $name = 'User';
public $belongsTo = array();
public $hasOne = array();
public $hasMany = array();
public $hasAndBelongsToMany = array(
'Othermodel' => array(
'className' => 'Othermodel',
'joinTable' => 'othermodels_users',
'foreignKey' => 'user_id',
'associationForeignKey' => 'othermodel_id',
'unique' => true
)
);
Again, I only have the relationship active in one place at one time, so I know the problem is not with the binding itself. It seems the problem is solely related to the fact that I have tried to use bindModel. Is this the intended behavior?
Based on the responses in this article, it looks like the bindModel function only exists for finds.
CakePHP: Bind Model not working
Though there's no information in the CakePHP 1.3 documentation that states that the bind is only for finds, though that would explain the behavior...
http://book.cakephp.org/1.3/en/The-Manual/Developing-with-CakePHP/Models.html
So, I am marking this as answered.
I'm not sure if this is relevant, but are you sure you are not doing any other find operations between the binding and the save. bindModel only binds the model for the next find operation so you may need to pass true through to bindModel to tell it to keep the binding around.
Relevant links: CakePHP: Bind Model not working and http://groups.google.com/group/cake-php/browse_thread/thread/316c9796603eac57?pli=1.
I hope this helps.
Try this,
$this->Message->bindModel(
array(
'belongsTo'=>array(
'User'=>array(
'foreignKey'=>false,
'conditions'=>array('Npl.to=User.id '),
'fields'=>array('recive')
),
'User_e'=>array(
'className'=>'User',
'foreignKey'=>false,
'alias'=>'User_e',
'conditions'=>array('Npl.from=User_e.id '),
'fields'=>array('recive')
)
)
)
);