Model is saving all fields, not just changed fields


#1

In http://book.agiletoolkit.org/model/core.html, there is a statement “Model automatically tracks fields which have been changed from its initial values”. (I understand this is an older documentation but it is a useful feature). When I save a form all of the values seem to be getting saved, which causes problems if mulitple people are working in different fields on the same form. What is the correct way to ensure only modified fields are saved?

Thank you,

Garrett


#2

ATK Data fully supports dirty values:

so when you load something from the database and attempt to save right away - it will not actually do anything. If you modify field value, it will be set as “dirty” and only dirty values are written back.

Some more info is here:

https://agile-data.readthedocs.io/en/develop/model.html?highlight=isdirty#Model::isDirty

If you have a case where non-dirty fields are saved ON UPDATE then it’s a bug.


#3

Actually I have noticed that if you do $model->save(['field' => 'current_value']); The current_value will be considered as dirty and tried to be updated even if it is not changed


#4

isDirty seems to compare the new form value with the database value, not the original form value. What I’m looking for is a standard way to only update fields in the database if the form field contents actually changed. Is there a way to do so?


#5

Model must be loaded to make sure record is deleted. If form contains same value as in the database - it shouldn’t be written. That’s how it should be.

@zak - save() calls set() so the way dirty values are treated shouldn’t be any different.


#6

@gcooka It should compare old DB value with new normalized field value. Can you please provide us with testcase (example) what’s going wrong for you? I have noticed such behaviour before too but not lately.
Maybe it’s related to default values or some custom persistence typecasting or value normalization?
Please help us find that and we will fix.


#7

Sure. Example is:

  1. Create form with multiple fields
  2. Open the form, and change value in one field but do not submit
  3. Open the same form in another session. Change the value in a different field, and submit it.
  4. Observe that the value modified in step 3 is shown in the database
  5. Submit the form from step 2
  6. Observe in the database that the value modified in step 3 has been changed back to the original value

Ideally, only values that the user actually changes would be written to the database. Right now when the old and new DB values are compared, is it using the original value (when the form was first opened) or the current value (after the other form has updated it)?


#8

What field types do you had for this test? Simple text fields?

Actually I can reproduce this issue. Will check more detailed sometime soon.
When saving form it is updating ALL fields, but data model should take care of not marking dirty fields which have not changed their value. Maybe something goes wrong there or it’s because of normalization or type casting.


#9

OK actually it’s all as expected and will not be changed.

Thing is that when you submit form, server receives ajax request. And at that moment form data model is loaded again from database (with actual values) and only then POSTed values are applied on loaded data model. So if you work in parallel in multiple browser instances you will have this behaviour. That’s normal - as expected. This way we can be sure about data integrity when multiple view instances share single data model record.


#10

Probably it would make sense to show an alert to the user that the data has changed? In VIM I have a similar warning, if I try to save an open file, that has been changed by other process.