I have the next tables in the database:
Lift
Vehicle
Manufacturer
Lift belongsTo Vehicle
Vehicle belongsTo Manufacturer
Manufacturer hasMany Vehicles
LiftsController.php add method:
public function add() {
if ($this->request->is('post')) {
$this->Lift->create();
$this->request->data['Lift']['user_id'] = $this->Auth->user('id');
if ($this->Lift->save($this->request->data)) {
$this->Session->setFlash(__('The lift has been saved'));
$this->redirect(array('action' => 'my_lifts'));
} else {
$this->Session->setFlash(__('The lift could not be saved. Please, try again.'));
}
}
$vehicles = $this->Lift->Vehicle->find('all', array('fields' => array('id', 'model', 'manufacturer_id')));
$towns = $this->Lift->TownFrom->find('list', array('order' => 'county ASC, name ASC', 'fields' => array('id', 'name', 'county')));
$this->set(compact('users', 'vehicles', 'towns'));
}
LiftsController.php add view:
echo $this->Form->input('vehicle_id');
A printscreen:
So what I need is to display instead of Manufacturer ID's the manufacturer name.
In every model the $displayField is set to the correct value
Try changing:
echo $this->Form->input('vehicle_id');
To
echo $this->Form->input('Vehicle');
Change
$vehicles = $this->Lift->Vehicle->find('all', array('fields' => array('id', 'model', 'manufacturer_id')));
To
$vehicles = $this->Lift->Vehicle->find('list', array('conditions' => array('Vehicle.user_id' => $this->Auth->user('id')), 'recursive' => 0, 'fields' => array('Vehicle.id', 'Vehicle.model', 'Manufacturer.title')));
Related
Before I would just ask user to confirm if he/she really wants to delete any instance like this:
$this->Html->link($this->Html->image('delete.png', array(
'alt'=>'delete', 'title'=>__('Delete'))),
array(
'controller' => 'users', 'action' => 'delete', $user['User']['id']),
array(
'escape'=>false, 'confirm'=>'Are you sure, you want to delete this user?'));
Right now user hasMany events, and I would like to check if he/she really does. That's no problem, so in the controller I would just try to get the first event his that user's id. But then, if there are any events, I would like to notify the users, that the deletion is not possible because there are related events.
I can go around and come up with some custom javascript solution, but there has to be a cake way to do it, it is just I cant find any.
Any suggestions?
Here is the controller action as of right now:
public function delete($id = null,$user_id = null) {
if (!$id) {
$this->Session->setFlash(__('Incorrect user id'));
$this->redirect(array('action'=>'index'));
}
if ($this->User->delete($id)) {
$this->Session->setFlash(__('User has been deleted'), 'positive_notification');
$this->redirect(array('controller'=>'full_calendar', 'action'=>'view_for', $user_id ));
}
$this->Session->setFlash(__('The user could not be deleted. Please try again.'), 'negative_notification');
$this->redirect(array('action' => 'index'));
}
Given that you have properly set up the model relationships like this:
//User.php
public $hasMany = array(
'Event' => array(
'className' => 'Event',
'foreignKey' => 'user_id'
),
//Event.php
public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
),
);
public function delete($id = null) {
if (!$id) {
$this->Session->setFlash(__('Incorrect user id'));
$this->redirect(array('action'=>'index'));
}
//check if User has Events
$user=$this->User->findById($id); //you can debug first the $user so you can know the values inside the array. Given that it has many Events, events associated to the User is in the $user
if(count($user["Event"])==0){ //if user has no events
if ($this->User->delete($id)) { //delete user
$this->Session->setFlash(__('User has been deleted'), 'positive_notification');
$this->redirect(array('controller'=>'full_calendar', 'action'=>'view_for', $user_id ));
}
else{
$this->Session->setFlash(__('The user could not be deleted. Please try again.'), 'negative_notification');
$this->redirect(array('action' => 'index'));
}
}
else{
$this->Session->setFlash(__('The user could not be deleted. Some events are associated to this User.'), 'negative_notification');
$this->redirect(array('action' => 'index'));
}
}
I am trying to get my edit to work I need the contact detail data to load when the user data loads. I have set the data in a similar manner to how I am retrieving the list of roles. I also don't know how to retrieve according to the model currently I was hard-coding it to retrieve 28. Would greatly appreciate any help provided.
public function edit($id = null) {
//Populate roles dropdownlist
$data = $this->User->Role->find('list', array('fields' => array('id', 'name')));
$this->set('roles', $data);
$data2 = $this->User->ContactDetail->find('first', array(
'conditions' => array('ContactDetail.id' =>'28')));
$this->set('contactdetails', $data2);
if (!$this->User->exists($id)) {
throw new NotFoundException(__('Invalid user'));
}
if ($this->request->is(array('post', 'put'))) {
if ($this->User->save($this->request->data)) {
$this->Session->setFlash(__('The user has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
} else {
$options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
$this->request->data = $this->User->find('first', $options);
}
}
my view is set up in the following manner
<?php echo $this->Form->create('User'); ?>
<fieldset>
<legend><?php echo __('Edit User'); ?></legend>
<?php
echo $this->Form->input('id');
echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Form->input('role_id');
echo $this->Form->input('ContactDetail.name');
echo $this->Form->input('ContactDetail.surname');
echo $this->Form->input('ContactDetail.address1');
echo $this->Form->input('ContactDetail.address2');
echo $this->Form->input('ContactDetail.country');
echo $this->Form->input('ContactDetail.email');
echo $this->Form->input('ContactDetail.fax');
?>
<label>Are you interested in buying property in Malta?</label>
<?php
$interest_buy = array('0'=>'no','1' => 'yes');
echo $this->Form->input('ContactDetail.interest_buy_property',array('type'=>'radio','options'=>$interest_buy,'value'=>'0','legend'=>FALSE));
?>
<label>Are you interested in renting property in Malta?</label>
<?php
$interest_rent = array('0'=>'no','1' => 'yes');
echo $this->Form->input('ContactDetail.interest_rent_property',array('type'=>'radio','options'=>$interest_rent,'value'=>'0','legend'=>FALSE));
echo $this->Form->input('ContactDetail.mobile');
echo $this->Form->input('ContactDetail.phone');
echo $this->Form->input('ContactDetail.postcode');
echo $this->Form->input('ContactDetail.town');
echo $this->Form->input('ContactDetail.newsletter',array('type'=>'checkbox','label'=>'Would you like to register for the newsletter?' ,'checked'=>'1','legend'=>FALSE,));
?>
?>
</fieldset>
<?php echo $this->Form->end(__('Submit')); ?>
User Model
public $primaryKey = 'id';
public $displayField = 'username';
public function bindNode($user) {
return array('model' => 'Role', 'foreign_key' => $user['User']['role_id']);
}
public function beforeSave($options = array()) {
$this->data['User']['password'] = AuthComponent::password(
$this->data['User']['password']
);
return true;
}
public $belongsTo = array(
'Role' => array('className' => 'Role'));
public $hasOne = array(
'ContactDetail' => array(
'foreignKey' => 'id'));
public $actsAs = array('Acl' => array('type' => 'requester', 'enabled' => false));
public function parentNode() {
if (!$this->id && empty($this->data)) {
return null;
}
if (isset($this->data['User']['role_id'])) {
$roleId = $this->data['User']['role_id'];
} else {
$roleId = $this->field('role_id');
}
if (!$roleId) {
return null;
} else {
return array('Role' => array('id' => $roleId));
}
}
}
ContactDetail Model
public $primaryKey = 'id';
public $displayField = 'name';
If I get you right, you have 1 contact details row for each user. In this case, you need to define in your User model:
public $hasOne = array(
'ContactDetail' => array(
'foreignKey' => 'id',
),
);
Like this, your ids will be synced in both tables. If you don't want to make the id a foreign key, you don't have to, it's just a suggestion.
Next, when you retrieve your data in the controller, you can do:
$this->User->Behaviors->load('Containable');
$user = $this->User->find('first', array(
'conditions' => array('User.id' => $id),
'contain' => array('ContactDetail'),
));
Now I don't know if there is an automated way to do this, but I sort my data manually to fill in the inputs. I am guessing you will get a structure like array('User' => array(), 'ContactDetail' => array()).
$user['User']['ContactDetail'] = $user['ContactDetail'];
unset($user['ContactDetail']);
$this->request->data = $user;
Then in your view just set the fields as the input array:
$this->Form->create('User');
$this->Form->input('User.some_user_field');
$this->Form->input('User.ContactDetail.some_contact_detail_field');
This should fill in your fields. When you go save your data, if your array is structured like this, you can use saveAssociated():
$this->User->saveAssociated($this->request->data, array('deep' => true));
EDIT
In case your relation is defined as User hasMany ContactDetail, then you need to structure your data like this:
$this->request->data = array(
'User' => array(
// user data
'ContactDetail' => array(
[0] => array(
//contact data
),
),
),
);
And in your view:
$this->Form->input('User.ContactData.0.field')
This is for 1 row only, If you need more rows on the child table with 1 input, do your logic accordingly.
Once your User model hasOne ContactDetail, you don't need retrieve the information twice, since you've done in $this->request->data line, all association model will retrieve too.
So, your Controller looks like this:
public function edit($id = null) {
if (!$this->User->exists($id)) {
throw new NotFoundException(__('Invalid user'));
}
// Roles
$roles = $this->User->Role->find('list', array('fields' => array('id', 'name')));
$this->set(compact('roles');
if ($this->request->is(array('post', 'put'))) {
if ($this->User->saveAll($this->request->data)) {
$this->Session->setFlash(__('The user has been saved.'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The user could not be saved. Please, try again.'));
}
} else {
$this->request->data = $this->User->read(null, $id);
}
}
And your View, for ContactDetail's fields looks like this:
echo $this->Form->input('ContactDetail.name');
And so for all the fields related to the model ContactDetail. You can find more details here: Saving Your Data.
User model:
public $hasOne = array(
'ContactDetail' => array(
'className' => 'ContactDetail',
'foreignKey' => 'user_id',
'dependent' => true
)
);
The best solution I have found is by setting
public $belongsTo = array(
'Role' => array('className' => 'Role')
, 'ContactDetail' => array('className' => 'ContactDetail'));
This way the contact detail data loads. Although the data once saved does not update contactdetails.
For me to save I used
$this->User->saveAll($this->request->data)
this worked fully
So currently I have two table products and orders. Relationship between them is many to many. Code I used in Model Product.php is
public $hasAndBelongsToMany = array
(
'Order'=>array
(
'joinTable' => 'ordersproducts',
'unique' => true,
'foreignKey' => 'productID',
'associationForeignKey' => 'orderID',
'order'=>'productID ASC'
)
);
Code I used in Model Order.php is
public $hasAndBelongsToMany = array
(
'Product'=>array
(
'joinTable' => 'ordersproducts',
'unique' => true,
'foreignKey' => 'orderID',
'associationForeignKey' => 'productID',
'order'=>'productID ASC'
)
);
Current function is add() which is admin can add order for customer. Function code in Order Controller is
public function add() {
if ($this->request->is('post'))
{
if ($this->request->is('post') || $this->request->is('put'))
{
$this->request->data['Product']['Product'] = array();
foreach($this->data['Product']['checkbox'] as $k=>$v)
{
if ($v) $this->request->data['Product']['Product'][] = $k;
}
//$this->Order->create();
if ($this->Order->saveAll($this->request->data)) {
$this->Session->setFlash(__('The order has been saved'),'default',array('class' => 'good'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The order could not be saved. Please, try again.'),'default',array('class' => 'error'));
}
}
}
$products = $this->Order->Product->find('list',array('fields'=>array('id','name')));
$this->set(compact('products'));
$customers= $this->Order->Customer->find('list',array('order'=>'cutomer_name ASC','fields'=>array('id','cutomer_name')));
$this->set(compact('customers'));
}
View for the adding order is:
foreach ($products as $id=>$label)
{
echo "<tr>";
echo "<td class='heading'>".$label."</td>";
echo "<td class='data'>";
echo $this->Form->input("Product.checkbox.$id", array('label'=>'','legend'=>false,'type'=>'checkbox',));
echo "</td>";
echo "</tr>";
}
As you can see I used checkbox for product list. Now I would like to know where should I add quantity and what changes do I need to make in Model relationship. I am not sure how to do it
One way to do it is to use the 'with' parameter for your HABTM relationship:
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasandbelongstomany-habtm
The 'with' parameter should reference an 'OrderItem' with foreign keys for order and product, with extra parameters for quantity, unit price, item name and whatever else you want to add.
Be careful with orders, you need to ensure that you don't normalise the data too much, as if your product changes price later on you don't want to lose the amount that the customer paid for this order item.
I have an add action form ProductsController which has many prices depending on the size. I am trying to save the product first and then within foreach loop the prices.
Some how saveAll or saveAssociated did not work.
public function add() {
if ($this->request->is('post')) {
$this->Product->create();
$product = $this->Product->save($this->request->data);
if (!empty($product)) {
$product_id = $this->Product->getInsertID();
$prices = $this->request->data['Product']['price'];
foreach ($prices as $price) {
$price['product_id'] = $product_id;
$this->Product->Price->save($price);
$this->Product->Price->id = false;
}
$this->Session->setFlash('The product has been saved.');
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash('Unable to add the product.');
}
}
}
The models are look like
class Product extends AppModel {
...
public $hasMany = array(
'Price' => array(
'className' => 'Price',
)
);
class Price extends AppModel {
public $belongsTo = array(
'Product' => array(
'className' => 'Product',
'foreignKey' => 'product_id',
)
);
}
You can use saveAssociated() as per documentation
But your view should look something like this:
echo $this->Form->create('Product', array('action' => 'add'));
echo $this->Form->input('Product.name', array('label' => 'Name'));
echo $this->Form->input('Product.description', array('label' => 'Description'));
echo $this->Form->input('Price.0.amount', array('label' => 'Amount'));
echo $this->Form->input('Price.0.price', array('label' => 'Price'));
echo $this->Form->end('Add');
I got problem when save belongto
class Script extends AppModel {
var $name = 'Script';
var $belongsTo = array(
'ScriptCatagories' => array(
'className' => 'ScriptCatagories',
'foreignKey' => 'script_catagories_id',
function add_script() {
pr($this->data);
if (!empty($this->data)) {
$this->Script->create();
$this->data['Script']['script_catagories_id'] = $this->Script->scriptCategory->id;
$this->data['Script']['user_id'] = $this->Auth->user('id');
if ($this->Script->save($this->data)) {
$this->Session->setFlash(__('The script has been saved', true));
$this->redirect(array('action' => 'script_index'));
} else {
$this->Session->setFlash(__('The script could not be saved. Please, try again.', true));
}
}
pr($scriptCatagories = $this->Script->ScriptCatagories->find('list'));
$this->set(compact('scriptCatagories'));
}
when click save
Array
(
[Script] => Array
(
[name] => fdfvvds
[description] => dfvdfvdfvdf
[tags] =>
)
)
Array
(
[0] => performance
[1] => cleanup
)
question in
$this->data['Script']['script_catagories_id'] = $this->Script->scriptCategory->id;
I need to save categoryid to script table but I don't know to get it
thank you
var $belongsTo = array(
'ScriptCatagories' => array(
'className' => 'ScriptCatagories',
'foreignKey' => 'script_catagories_id',
first, it doesn't have close parentheses. And it should be singular ScriptCategory, also the foreign key script_category_id (just to follow the convention). And you misspelled category (you have $this->Script->scriptCategory->id; later in the code)