Model won't update - cakephp

Using cakephp:
I am trying to update customer information and the address the customer is linked to.
such that Customer.address_id = Address.id, and
Customer Model
$belongsTo = 'Address';
From the customers_controller
function profile($id = null)
{
if (empty($this->data['Customer']))
{
$this->Customer->id = $id;
$this->data = $this->Customer->read();
}
else
{
$this->Customer->id = $this->data['Customer']['id'];
$this->Customer->read();
$this->Customer->save($this->data['Customer']);
$this->Customer->Address->save($this->data['Address']);
}
}
Customer correctly updates, but Address always inserts a new row. How do I get this address to update?

first of all, take away lines 11 and 12. those serve no purpose. make sure your view contains form elements for Customer.id and Address.id. If you are just updating the Address you dont need line 13 either. The short answer is that Cakephp will insert row instead of update if the primary key is missing. In your case this means [Address][id].

Related

MVC Model is using values for old table entries, but new entries return NULL

I have an interesting little problem. My controller is assigning values to the properties in my model using two tables. In one of the tables, I have some entries that I made a while ago, and also some that I've just added recently. The old entries are being assigned values correctly, but the new entries assign NULL even though they're in the same table and were created in the same fashion.
Controller
[HttpPost]
[Authorize]
public ActionResult VerifyReservationInfo(RoomDataView model)
{
string loginName = User.Identity.Name;
UserManager UM = new UserManager();
UserProfileView UPV = UM.GetUserProfile(UM.GetUserID(loginName));
RoomAndReservationModel RoomResModel = new RoomAndReservationModel();
List<RoomProfileView> RoomsSelectedList = new List<RoomProfileView>();
GetSelectedRooms(model, RoomsSelectedList);
RoomResModel.RoomResRmProfile = RoomsSelectedList;
RoomResModel.GuestId = UPV.SYSUserID;
RoomResModel.FirstName = UPV.FirstName;
RoomResModel.LastName = UPV.LastName;
RoomResModel.PhoneNumber = UPV.PhoneNumber;
return View(RoomResModel);
}
GetUserProfile from the manager
public UserProfileView GetUserProfile(int userID)
{
UserProfileView UPV = new UserProfileView();
ResortDBEntities db = new ResortDBEntities();
{
var user = db.SYSUsers.Find(userID);
if (user != null)
{
UPV.SYSUserID = user.SYSUserID;
UPV.LoginName = user.LoginName;
UPV.Password = user.PasswordEncryptedText;
var SUP = db.SYSUserProfiles.Find(userID);
if (SUP != null)
{
UPV.FirstName = SUP.FirstName;
UPV.LastName = SUP.LastName;
UPV.PhoneNumber = SUP.PhoneNumber;
UPV.Gender = SUP.Gender;
}
var SUR = db.SYSUserRoles.Find(userID);
if (SUR != null)
{
UPV.LOOKUPRoleID = SUR.LOOKUPRoleID;
UPV.RoleName = SUR.LOOKUPRole.RoleName;
UPV.IsRoleActive = SUR.IsActive;
}
}
}
return UPV;
}
The issue I see is that this database has a somewhat poor design, and that particular record fell into the trap of that poor design. Consider that you have two ID's on that table:
SYSUserProfileID
SYSUserID
That's usually an indication of a bad design (though I'm not sure you can change it), if you can, you should merge anything that uses SYSUserID to use SYSUserProfileID.
This is bad because that last row has two different ID's. When you use db.Find(someId) Entity Framework will look for the Primary Key (SYSUserProfileID in this case) which is 19 for that row. But by the sounds of it, you also need to find it by the SYSUserID which is 28 for that row.
Personally, I'd ditch SYSUserID if at all possible. Otherwise, you need to correct the code so that it looks for the right ID column at the right times (this will be a massive PITA in the future), or correct that record so that the SYSUserID and SYSUserProfileID match. Either of these should fix this problem, but changing that record may break other things.

Apex Trigger with custom objects

2 custom objects
1.Merchandise
2.invoice
whenever a new merchandise is created an auto invoice has to be created.As am new to apex,please bear with me.Any one please correct my code.
code:
trigger createinvoice on Merchandise2__c (after insert,after update) {
list<Invoice2__c>line = new list<Invoice2__c>();
for(Merchandise2__c mer:Trigger.new){
Invoice2__c li = new Invoice2__c();
line =[select id from Invoice2__c ];
li.name = mer.Name;
li.Status__c='open';
li.id = mer.id;
line.add(li);
}
insert line;
}
First remove the after update from your trigger unless you want a new invoice created each time someone updates the Merchandise record.
I'm not sure what you were trying to accomplish with the select line.
"line =[select id from Invoice__c];" this doesn't seem to accomplish anything. Also you're trying to set the id field of the invoice to the id of the merchandise record. You can't do that. You'll need a lookup field on the Invoice record that points to merchandise. Below I called it merchandiseKeyField.
Hope this helps.
trigger createinvoice on Merchandise2__c (after insert,after update) {
//if you don't remove after Update then check which trigger
if(Trigger.IsInsert){
list<Invoice2__c> invoices = new list<Invoice2__c>();
for(Merchandise__c mer: trigger.new){
invoices.add(new Invoice2__c(li.name = mer.name,
li.merchandiseKeyField = mer.id);
}
insert invoices;
}
}
replace your loop with this:
for(Merchandise2__c mer:Trigger.new){
Invoice2__c li = new Invoice2__c();
li.name = mer.Name;
li.Status__c='open';
line.add(li);
}

cakephp - using create() not working as expected

I have a product controller and when I'm saving a new product I want to save some records to another related controller to make a record of what categories the product is associated with.
My code I'm using is:
$this->Product->create();
if ($this->Product->save($this->request->data)) {
$newProductId = $this->Product->getInsertID();
//associate products with categories
foreach($categoriesToSave as $key=>$value) {
$saveArray['CategoriesProduct'] = array('category_id'=>$value, 'product_id'=>$newProductId);
$this->Product->CategoriesProduct->create();
$this->Product->CategoriesProduct->save($saveArray);
$this->Product->CategoriesProduct->clear();
}
}
For some reason though, even if $categoriesToSave has 10 items in it, only the very last one is being saved. So it's obviuosly creating only the one new CategoriesProduct item and saving each record over the top of the last instead of create()-ing a new one.
Can anyone explain what I'm doing wrong and how I can make this work?
The way I would do it would be like this:
//Add a counter
$c = 0
foreach($categoriesToSave as $key=>$value) {
$saveArray[$c]['CategoriesProduct']['category_id'] = $value;
$saveArray[$c]['CategoriesProduct']['product_id'] = $newProductId;
$c++;
}
$this->Product->CategoriesProduct->saveMany($saveArray);
I don't think that is the only way to do it but that should work just fine.
Good luck!

drupal_write_record doesn't take object

In drupal 6 i used to do something like this:
<?php
/*
* CLASS Example
*/
class example {
var $id = NULL;
var $title;
var $body;
.....
// Save
function save() {
$primary_key = ($this->id == NULL ? NULL : 'id');
if (drupal_write_record('mytabble', $this, $primary_key)) {
return TRUE;
} else {
return FALSE;
}
}
}
?>
This worked quite well. But in Drupal 7, the drupal_write_record only takes an array and no longer the object $this. The new db_merge also only takes an array.
Since i want to save the properties of my object to the database, the above code was very handy and generic for all kinds of classes.
Is there an alternative way to write an object to database, or a method to place objectproperties into a an array?
Any help will be appreciated!
Robert
drupal_write_record does take an object or an array. Guess your problem is caused somewhere else.
drupal_write_record($table, &$record, $primary_keys = array())
$record: An object or array representing the record to write, passed in by reference. If inserting a new record, values not provided in $record will be populated in $record and in the database with the default values from the schema, as well as a single serial (auto-increment) field (if present). If updating an existing record, only provided values are updated in the database, and $record is not modified.
More info on drupal_write_record for D7.

CakePHP is updating when it should be inserting a HasAndBelongsToMany model

I have a small problem. I am making a site that has Tags and Questions. I have a Question model, Tag model, QuestionsTag model, everything fits together nicely. The user upon asking something puts the tags in the field seperated by a space (foo bar baz) much like on stackoverflow.com.
Now, here is the code to check if a tag already exists or not and entering the tag into the database and the required associations:
function create () {
if (!empty($this->data)) {
$this->data['Question']['user_id'] = 1;
$question = $this->Question->save ($this->data);
/**
* Preverimo če se je vprašanje shranilo, če se je,
* vprašanje označimo.
*/
if ($question) {
$tags = explode (' ', $this->data['Question']['tags']);
foreach ($tags as $tag){
if (($tagId = $this->Tag->existsByName($tag)) != false) {
/**
* Značka že obstaja, torej samo povezemo trenuten
* id z vprašanjem
*/
$this->QuestionsTag->save (array(
'question_id' => $this->Question->id,
'tag_id' => $tagId
));
}
else {
/**
* Značka še ne obstaja, jo ustvarimo!
*/
$this->Tag->save (array(
'name' => $tag
));
// Sedaj pa shranimo
$this->QuestionsTag->save(array(
'question_id' => $this->Question->id,
'tag_id' => $this->Tag->id
));
$this->Tag->id = false;
}
; }
}
}
}
The problem is this, a Question has an id of 1 and I want it to have the tags with id of 1, 2, 3.
When the 2nd and 3rd save get called, Cake sees that in the questions_tags table is already a question with id 1, so it just updates the tag.
But this is not correct, as there should be many questions in that table with the same id, as they refer to different tags belonging to them.
So, is there a way to prevent this? Prevent the save method from UPDATEing?
Thank you!
This behavior isn't specific to HABTM relationships. You are calling the save() method inside of a loop. After the first save, an id value is set and each subsequent save call sees the id and assumes it's an update. Within a loop, you first need to call model->create() to reset an id value that may exist.
From the CakePHP Docs at http://book.cakephp.org/view/75/Saving-Your-Data:
When calling save in a loop, don't forget to call create().
In your case, it would look like this:
$this->QuestionsTag->create();
$this->QuestionsTag->save (array(
'question_id' => $this->Question->id,
'tag_id' => $tagId
));
Check out saveAll. You can make a single call to $this->Question->saveAll(), and it will save any associated data you supply as well. Note that with HABTM data, it will perform a DELETE for any questions_tags associated with that question_id, then perform an INSERT for all the tag_id's included with your data.
if you want to make sure, that a new entry (INSERT) is made rather then an update, you can set $this->create(); right in front of the save call. See http://book.cakephp.org/view/75/Saving-Your-Data (in the upper part of the page): When calling save in a loop, don't forget to call create().

Resources