How MVC Update Model works with incomplete objects? - asp.net-mvc

I have a view that is bound to an object called "Requisition"
On this view we are only modifying is child records.
My question is: When I submit the form I have the object requisitionForm, and this object is only partially complete.
How do I save just the new changes?
Should I take the requisitionForm (incomplete) and merge it with requisition (complete) ?
thanks!

Remove the requisitionForm parameter, and call UpdateModel(requisition)

Is this what you want? http://www.joe-stevens.com/2010/02/17/asp-net-mvc-using-controller-updatemodel-when-using-a-viewmodel/

Related

Looping through list of objects created by createEntry() and editing their properties before doing submitChange()

Good afternoon fellow developers,
I have come across a scenario where I found myself needing to retrieve the list of pending changes from my model and editing a specific property of those entries before sending them to my back-end.
These are new entities I created using the createEntry() method of the OData model v2. But, at the time of creation of said entities, I do not possess the value I need to add to them yet. This is the list of entities I retrieve by using the getPendingChanges() method on my model:
What I need to do is to loop through each of these newly created entities and set a specific property into them before actually sending them to my back-end with the submitChanges() method. Bare in mind that these are entry objects created by the createEntry() method and exist only in my front-end until I am able to submit them with success.
Any ideas that might point me in the right direction? I look forward to reading from you!
I was able to solve this issue in the following way:
var oPendingChanges = this.model.getPendingChanges();
var aPathsPendingChanges = $.map(oPendingChanges, function(value, index) { return [index];});
aPathsPendingChanges.forEach(sPath => oModel.setProperty("/" + sPath + "/PropertyX","valueFGO"));
The first two instructions retrieve the entire list of pendingChanges objects and then builds an array of paths to each individual entry. I then use that array of paths to loop through my list of pending changes and edit into the property I want in each iteration of the loop. Special thanks to the folks at answers.sap for the guidance!

Hydrating Database

I am new to learning and understanding how Hydration works, just wanted to point that out first. I'm currently able to Hydrate Select and Insert queries without any problems.
I am currently stuck on trying to Hydrate Update queries now. In my entity I have setup the get/set options for each type of column in my database. I've found that the ObjectProperty() Hydrator works best for my situation too.
However whenever I try to update only a set number of columns and extract via the hydrator I am getting errors because all the other options are not set and are returning null values. I do not need to update everything for a particular row, just a few columns.
For example in my DB Table I may have:
name
phone_number
email_address
But I only need to update the phone_number.
$entity_passport = $this->getEntityPassport();
$entity_passport->setPrimaryPhone('5551239876');
$this->getTablePassport()->update($this->getHydrator()->extract($entity_passport), array(
'employeeid' => '1'
));
This returns an error because setName() and setEmailAddress() are not included in this update and the query returns that the values cannot be null. But clearly when you look at the DB Table, there is data already there. The data that is there does not need to be changed either, only in this example does the PrimaryPhone() number.
I've been looking and reading documentation all over the place but I cannot find anything that would explain what I am doing wrong. I should note that I am only using Zend\Db (Not Doctrine).
I'm assuming I've missed something someplace due to my lack of knowledge with this new feature I'm trying to understand.
Perhaps you don't Hydrate Update queries... I'm sort of lost / confused. Any help would be appreciated. Thank you!
I think you're having a fundamental misconception of hydration. A hydrator simply populates an entity object from data (hydrate) and extracts data from an entity object (extract). So there are no separate hydrators for different types of queries.
In your update example you should first retrieve the complete entity object ($entity_passport) and then pass it to the TableGateway's update method. You would retrieve the entity by employeeid, since that's the condition you're using to update. So something like this:
$entity_passport = $passportMapper->findByEmployeeId(1);
$entity_passport->setPrimaryPhone('5551239876');
$this->getTablePassport()->update($this->getHydrator()->extract($entity_passport), array(
'employeeid' => $entity_passport->getId()
));
This is assuming you have some sort of mapper layer. Otherwise you could use your passport TableGateway (I assume that's what getTablePassport() returns, no?).
Otherwise, if you think retrieving the object is too much overhead and you just want to run the query you could use just a \Zend\Db\Sql\Sql object, ie:
$sql = new \Zend\Db\Sql\Sql($dbAdapter);
$update = $sql->update('passport')
->set(array('primary_phone' => $entity_passport->getPrimaryPhone()))
->where(array('employeeid' => $employeeId));
Edit:
Maybe it was a mistake to bring up the mapper, because it may cause more confusion. You could simply use your TableGateway to retrieve the entity object and then hydrate the returned row:
$rows = $this->getTablePassport()->select(array('employeeid' => 1));
$entity_passport = $this->getHydrator($rows->current());
[...]
Edit 2:
I checked your gist and I noticed a few things, so here we go:
I see that your getTablePassport indeed does return an object which is a subclass of TableGateway. You have already set up this class for it to use a HydratingResultset. This means you don't need to do any manual hydrating when retrieving objects using the gateway.
You also already implemented a Search method in that same class, so why not just use that? However I would change that method, because right now you're using LIKE for every single column. Not only is it very inefficient, but it will also give you wrong results, for example on the id column.
If you were to fix that method then you can simply call it in the Service object:
$this->getTablePassport->Search(array('employeeid' => 1));
Otherwise you could just implement a separate method in that tablegateway class, such as
public function findByEmployeeId($employeeId)
{
return $tableGateway->select(array('employeeid' => $employeeId));
}
This should already return an array of entities (or one in this specific case). P.S. make sure to debug and check what is actually being returned when you retrieve the entity. So print_r the entity you get back from the PassportTable before trying the update. You first have to make sure the retrieval code works well.

Only update records that haven't been updated

When creating a record i know you can use the method
.first_or_create!
to create records that don't already exist in the model. I need to do the same for when updating a model. I have an app that runs a rake task to apply a score to a column in my model.
prediction.update_attributes!(score: score)
I only want to update the scores that have not been updated yet.
is this possible?
Thanks
I think you might be looking for the try method which will attempt to call a method on an object that is potentially nil.
Example:
>> prediction.try(:update_attributes!, :score => some_new_score)
If prediction is nil it will just return nil, not throw a NoMethodError. If prediction is an object representing an existing record, then it will call the method on the object and update its score attribute.
http://api.rubyonrails.org/classes/Object.html#method-i-try
I agree with juanpastas that Rails will only save to the db if something has actually changed. IF you want to be more explicit in your code, Why not use the '.changed?' flag to save only dirty records? Look here for more details.

Binding to observable collection getting element onTapp

i use a observable collcetion to bind data to a GridView (with an itemTemplate). The template includes an item that can be rightTapped. Is there any nice way to get the element (the one in the observable collection) in the rightTapped event handler?
Thank you
Yes , youcan get the value from senderitem.datacontext (you would need some typecasting).

Update only the changed values on Entity object

how can i automatically update my entity objects changed values and save them to db.
I hava an Action like that
public ActionResult Update()
{
User userToUpdate = new User();
TryUpdateModel<User>(userToUpdate,ValueProvider);
BaseRepository.Context.AttachTo("User",userToUpdate);
BaseRepository.Context.SaveChanges();
return Json("");
}
ValuProvider : has the items that come
from the client as post data.
The problem on this code is the code update all the values but i want to update only the changed values.
How can i find the changed values on my entity object.
You should check out the ObjectContext.ApplyPropertyChanges Method
it is suppose to do what your asking for...
msdn
Two options:
On the View you could know the values that were changed by using Javascript and then you could pass that information to your controller.
You could simply compare the previous values (which you already have since you populated a view) and check each value before updating the DB.
I prefer last option, since at this point you could also check for data validation.
This is really a problem for your data access code, not anything to do with your controller. Pick an ORM that handles this for you and forget about the problem.

Resources