문제

I created a search page that returns sets records using a custom controller and a Visualforce page. Users can update specific fields on individual records.

I want to have the ability to save all the changed records at once, but the action command updates the entire return set--not just the changed records. The app requires that only the modified records are updated.

Short of filtering for every possible change that can be made on a record or putting a save button on each record, does anyone have a creative idea on how to identify the specific records that were modified so the app can save just those that were edited?

도움이 되었습니까?

해결책

Very interesting question :)

There's a cool answer on SFSE about tracking changes between "old" and "new" via either field describe or JSON serialization: Generically walk sObject fields. Note that I've linked to the answer I consider most neat, consider reading whole page!

This question is interesting also because it'd put your logic in the more correct place - in the trigger. Because you should ask yourself if it's not OK to make an update that doesn't really change anything on your search page - should it also be possible on other pages?


If that's not something that would work for you here's another interesting trick.

Sets internally use object's hash to determine uniqueness (not just Id, all fields). It's perfectly fine to have set like that:

Set<User> users = new Set<User>();

User u1 = new User(Id = UserInfo.getUserId());
User u2 = new User(Id = UserInfo.getUserId(), LastName = 'Doe');

users.add(u1);
users.add(u2);

System.assert(users.contains(u2));

u2.FirstName = 'John';

System.assert(users.contains(u2), users); // boom, headshot. It was there a minute ago, I swear!

Usually this is a disadvantage and we're told to use Map<Id, sObject> instead so the key/hash/whatever doesn't change. But in your case - you could use it as intended feature.

Try this (untested):

  1. Fetch your search results as you do currently.
  2. User changes none/some/all and hits "submit".
  3. Throw that list into a helper Set<sObject> (use addAll method).
  4. Fetch search results again to another helper list. Make sure you've queried for exactly same fields.
  5. Call mySet.removeAll(originals); - should wipe out all items that are identical.
  6. Throw the survivors into a final helper list and call update on it.

This has some downsides, for example if somebody modified one of records in the meantime - the query from #4 will yield different results... You could deal with it by storing a hidden copy of original search results and comparing these (read about List.deepClone) - but this will mean doubling your viewstate!

(we might get hash code conflicts too with right set of data - maybe just ditch the removeAll and go with equals on each item. I hope I gave you some food for thought)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top