cake - Confused about how to count data - cakephp

I know this question is very simple. But I fail to find it in Google. I'm very new to cake afterall.
For example I have two Model: Product and Category.
In Product index I want to show a list of available Categories and the amount of Products in that category. Like below:
Food (10)
Beverages (7)
...
I successfully looped the available categories, but not sure how to count it. Below is my loop:
<?php foreach($categories as $c): ?>
<li> ... <?php echo $this->$c->Product->find('count') ?> </li>
<?php endforeach; ?>
// The ... part is echo-ing the category name
I tried many variations and keep getting error like ArrayHelper not found or ProductHelper not found
Anyone have the solution?
Thanks
EDIT
This is my ProductController code before I added the foreach loop you suggested.
public function index() {
//the first two lines is default from cake bake
$this->Product->recursive = 0;
$this->set('products', $this->paginate());
$categories = $this->Product->Category->find('all');
$this->set('categories', $categories);
}

Instead of calculating the count on each request, use the counter cache feature to store the products count for each category and then simply display that.

you are trying to call model in view file, instead you could add the product count to your array from controller itself, like, example code would be:
in your controller:
$categories = $this->Product->Category->find('all',array('recursive'=>-1));
foreach($categories as $key => $category){
$categories[$key]['ProductCount'] = $this->Product->find('count',
array(
'conditions'=>array('Product.category_id'=>$category['Category']['id'])
)
);
}
where ProductCount can be replaced by name of the product

Related

cakephp getLastInsertId not working

Here I have used cakephp js helper to send data,After insert One data I need this last id for farther work.Here I have tried bellow code in Addcontroller
if ($this->Patient->save($this->request->data)) {
$lastid=$this->Patient->getLastInsertId();
$patient=$this->Patient->find('all',array(
'conditions'=>array('Patient.id'=>$lastid ),
'recursive' => -1
));
$this->set('patient', $patient);
}
In add.ctp I have tried bellow code but I haven't get last id here.
<?php foreach ($patient as $patient): ?>
<?php echo h($patient['Patient']['id']); ?>
<?php endforeach; ?>
Method getLastInsertId() return id of just saved records.
If you need this id in your view just after save, you must first set that variable in your controller like $this->set(compact('lastid','patient'); and then use in view <?php echo $lastid; ?>
use
if ($this->Patient->save($this->request->data)) {
$id = $this->Patient->id;
$patient=$this->Patient->find('all',array('conditions'=>array('Patient.id'=>$id),'recursive' => -1));
$this->set->('patient', $patient);
//If you are saving the record with ajax which it looks like you
//might be from your question you will need the following instead
//of $this->set->('patient', $patient); try:
return json_encode($patient);
You will then also need to update your js ajax call, you will have a json array to decode so parse it with jquery and append it back into your view.
Cake will always give you the id of record you have just saved, by simply adding $id = $this->MyModel->id; You can use the id to query for the record.
Try below code:
In controller:
$lastid=$this->Patient->getLastInsertId();
$this->set(compact('lastid','patient');
Then use $lastid in View file.
In controller:
$lastid=$this->Patient->getLastInsertId();
$patient['Patient']['last_id'] = $lastid;
then use $patient['Patient']['last_id'] in your view file.

CakePHP 2.x Accessing Another Model

Noob to cakePHP here.
Bicycle belongsTo Stand
Stand hasMany Bicycle
Stand belongsTo Station
Station hasMany Stand
I've baked the CRUDs and now I want to display the station name when I view a bicycle. How should I define the bicycle - station relationship? Or what do I need to do to include the station model in the bicycles controller?
What I've tried so far. Which throws a "Notice (8): Undefined index: Station":
BicyclesController.php:
public function index() {
$this->Bicycle->recursive = 2;
$this->set('bicycles', $this->Paginator->paginate());
}
index.ctp:
<?php echo $this->Html->link($bicycle['Station']['name'].$bicycle['Stand']['stand_no'], array('controller' => 'stands', 'action' => 'view', $bicycle['Stand']['id'])); ?>
Help!
Since you have no direct relationship from Bicycle to Station, its not going to be available within $bicycle['Station'] Its more likely to be available in $bicycle['Stand']['Station]['name'].
In order to see if its actually being returned with recursive set as it is, I would run the query again and call $debug($bicycle);die; in the following order.
public function index() {
$this->Bicycle->recursive = 2;
$bicycles = $this->Paginator->paginate();
$debug($bicycle);die;
$this->set(compact('bicycles'));
}
This will kill the model at this point and display an array of results returned. You will then see where the information you want is, and how to access it. Just remove the $debug line when finished.

Look up data from a diffrent model using Cake

im new to cake (and loving it) but i have hit a problem that i cant seem to find a solution to. Im pretty sure there is an obvious answer to this so my apols in advance if i am asking a stupid question.
Okay, here goes.
I am trying to build a simple message system using Cake PHP version 2.
I have two models at the moment, one handles users (used for loggin in and out) and the other handles messages.
In the messages table i have the following columns:
id | sender_id | recipient_id | subject | body
My MessagesController.php reads as follows:
class MessagesController extends AppController {
public function recent_messages() {
if (empty($this->request->params['requested'])) {
throw new ForbiddenException();
}
return $this->Message->find(
'all'
);
}
}
My View is located in my elements as it actually displayed as a drop down in my navbar. Here is my view:
<?php
$messages = $this->requestAction('/messages/recent_messages');
?>
<?php
foreach ($messages as $message): ?>
<li>
<a href="#">
<div> <strong>Username of sender goes Here</strong></div>
<div><?php echo $message['Message']['subject']; ?></div>
</a>
</li>
<li class="divider"></li>
<?php endforeach; ?>
What i would like to do is to be able to get the actual username of the message sender using the sender_id. Just to clarify the sender_id value is actually the id (primary key) of the user in the users table.
Initially i thought this would be done through setting an association but i cant see how.
If anyone could offer any advice on this i would be most grateful.
I don't understand why you are using $this->requestAction
if your view is recent_messages.ctp you are already calling recentMessages().
Then if you set your relationships you are already retrieving all the data you need
$message['Sender']['username']
contains the information you are looking for. (or $message['User']['username'] it depends on how you wrote your model).
If not read the Manual about setting the relationships.
In brief all you have to do in your Message model is
$belongsTo = array(
'Sender' => array(
'className' => 'User',
'foreignKey' => 'sender_id'
)
)
One further thought.
It seems that you are doing the requestAction from the view. I think it can only be done from the controller and then you pass the result to the view via the $this->set('messages', $message) command.
If I've misinterpreted what you are doing then I'm sorry.

cakephp view printing out the same values from database

created a view function and any time i click the link to view a template, the url at the top of the page is correct but it spits out the same list of fields in the database.
the fields are
accounts - id, company name, abn
template - id, name, description, account_id
field - id, name, field type, template_id
function view(){
$accounts=$this->User->AccountsUser->find('list',
array('fields'=>array('id', 'account_id'),
'conditions' =>array('user_id' =>
$this->Auth->user('id'))));
$templates=$this->Template->find('first',
array('conditions' => array(
'Template.account_id' => $accounts)));
$fields=$this->Field->find('all',
array('conditions' => array(
'Field.template_id' => Set::extract('/Template/id', $templates))));
$this->set('template', $templates);
$this->set('account', $accounts);
$this->set('field', $fields);
}
here is the view
<div class = "conlinks">
</br></br></br></br></br><h2>Here is your template fields</h2></br>
<?php foreach($field as $fields): ?>
<tr>
<td align='center'><?php echo $fields['Field']['name']; ?>
</tr></br>
<?php endforeach; ?>
</div>
so the problem is its grabbing the exact same list of fields, not the correct template_id when it prints out the fields
You should be able to debug this for yourself. Just narrow the bug down step by step.
For starters, in your view function, do a print_r on the following variables, and make sure each one contains a logical result:
$accounts
$templates
$fields
If you find unexpected results there, I'd be looking at the parameters you pass into each of your finds, and making sure they're OK. You're passing in $accounts as an array to your find condition - make sure it matches the format that cake expects. Do the same for Set::extract('/Template/id', $templates).
Also look at the SQL that Cake is producing.
If you're not already using it, I'd highly recommend installing Cake's Debug Kit Toolbar - https://github.com/cakephp/debug_kit/ because it makes debugging variables and SQL much easier.
If you do the above steps and can't solve your problem, you should at least be able to narrow it down to a line or two of code. Update your answer to show what line or two is causing the problem, and include print_r's of some of the variables you're working with. That should help others on StackOverflow to give you a specific answer.
Hope that helps!
the issue was I wasn't getting the parameters when click the link
function view($name){
$fields = $this->Template->Field->find('list',array(
'fields'=> array('name'),
'conditions' => array(
'template_id'=> $name)));
$this->set('field', $fields);
}
and the view
<div class = "conlinks">
</br><h2>Here is your template fields</h2>
<?php foreach($field as $name): ?>
<tr>
<td align='center'>
<?php echo $name; ?>
</tr></br>
<?php endforeach; ?>
</br>
<?php
echo $this->Html->link('Back', '/templates/view', array('class' => 'button'));?>
</div>

CakePHP How to echo just one record

I want to echo a full name from my MySQL database in my header. When that name is clicked in a list it filters all the records and displays all the records related to that name only. I managed to get the filter working, but not able to display the name in header.
<? $this->read('$jobs as $row'); ?>
<h1><?=$row['Employee']['first_name']?> <?=$row['Employee']['last_name']?>'s Jobs</h1>
<? $this->end(); ?>
If I'm not wrong, you are trying to retrieve this array, I'm assuing $jobs contains single row.
try this
<?php
if (isset($jobs)) {
foreach($jobs as $row){
if (isset($row['Employee']['last_name']))
$last = $row['Employee']['last_name'];
$first = 'N/A';
if (isset($row['Employee']['first_name']))
$first = $row['Employee']['first_name'];
?>
<h1><?php echo $first.' '. $last?>'s Jobs</h1>
<?php } }?>
OR
<h1><?php isset($jobs[0]['Employee']['first_name']) ? $jobs[0]['Employee']['first_name'] : 'N/A' .' '. isset($jobs[0]['Employee']['last_name']) ? $jobs[0]['Employee']['last_name'] : 'N/A'?>'s Jobs</h1>
This can be much more easily achieved through the use of virtual fields. The example in the Cake book is practically identical to your needs.
Just add this to your Employee model:
public $virtualFields = array(
'full_name' => 'CONCAT(Employee.first_name, " ", Employee.last_name)'
);
Now [Employee]['full_name'] can be used without having to use any logic.
Here's the link to the Cake book page covering virtual fields: http://book.cakephp.org/2.0/en/models/virtual-fields.html

Resources