My application is document based and uses Core Data. I want to create some initial entities when a new document is created. I use NSEntityDescription.insertNewObject, but then the document is considered edited and there is an action that can be undone an redone. How do I prevent this?
Set your document's undoManager to nil (keep a reference to it) before inserting your boilerplate objects, then set it back.
Related
I have a database called "development-records" that has a MapReduce view with a "dbcopy" declaration that creates a view in a new database called "development-chained".
When we make an update the view in "development-records", we do the usual steps of:
1. Create a duplicate copy of the design document that we want to change, for example by adding _OLD to its name: _design/fetch_OLD.
2. Put the new or 'incoming' design document into the database, using a name with the suffix _NEW: _design/fetch_NEW.
3. Query the fetch_NEW view, to ensure that it starts to build.
4. Poll the _active_tasks endpoint and wait until the index has finished building.
5. Put a duplicate copy of the new design document into _design/fetch.
6. Delete Design Document _design/fetch_NEW.
7. Delete Design Document _design/fetch_OLD.
The problem is that the documents specified in the dbcopy database "development-chained" don't seem to be updated -- all the old records stay. Is there a way to trigger the dbcopy database to perform the MapReduce again?
Unfortunately, according to the official Cloudant documentation, "The dbcopy feature can cause problems under some circumstances." Use of this feature is strongly discouraged, and has otherwise been removed from the documentation. I hope knowing that helps a little. The new documentation is hard to find.
is there a simple and efficient/fast way to query a managedobjectcontext to get an array of all the managedobjects in the context that have not yet been added to the persistent store?
i ask this because i would like to be able to save nsmanagedobjects that have been added to the MOC only if they conform to certain criteria. basically i want to be able to do this so that if some unexpected event happened before my managed object attributes were properly populated, i can catch this fact and purge the object(s) before saving the context. given the complexity of the navigation possible in the app, i'd like to have a look at the data to be sure they are good before i save.
i suppose i could also do this with some kind of validation rule and a flag field that doesn't get set until i am sure the user has added all the data to the record, but i don't yet know how to implement this...
any help much appreciated.
The insertedObjects method of NSManagedObjectContext
returns the set of objects that have been inserted into the context but not yet saved in a persistent store.
I have a strange thing, I'm using dynamic field binding in a custom control.
The field binding is created like this.
XPage (Datasource "document" is placed here)
Custom Control (String passed in)
(to get errors if there are any)
Repeat (CompositeData is passed to a bean that returns the strings for Rows,columns)
Repeat (repeat 1 variable used for Columns)
Custom Control (fieldname is passed in)
field binding is done like this
#{document[compositeData.fieldName]}
The problem is that when I save the XPage I get an error in the messages control
Document has been saved by another user - Save created a new document as a response to that modified document.
And all fields are cleared.
Any ideas how to debug this or is there something I'm missing?
The "Document has been saved by another user" error is only tip of the iceberg - there are some really strange problems with reapeats that repeats fields that are bound and repeatControls property is set to false. The decoding part of xpages lifecycle cannot handle it properly - the controls will be losing data. You should use repeatControls set to true as Martin suggests.
"Repeat control variable doesn't exists" is probably caused by the property that removes repeats set to true. You can solve this by either changing it to false or by adding additional data context that will keep repeated value.
And finally for this to have add/remove functionality You can use Dynamic Content Control and show(null) hack to rebuild the repeat content.
To manage this complexity better I would advise You to stop using document data source and start creating some managed beans.
If You will follow my suggestions I guarantee that You will get the functionality You are looking for as I have few apps that works great and have this kind of complex data editors in them.
I don't know if it'll help you, but I pass both the document datasource and the field name as parameters to a DynamicField control, and use it like this:
compositeData.dataSource[compositeData.fieldName]
The type of the datasource is com.ibm.xsp.model.DataSource, it's listed as dataInterface under Data Sources.
Do you have repeatControls="true" set for the repeat control?
It sounds like you've got the datasource defined multiple times on the XPage (plus custom controls). Either that or the save button has save="true" but the code saves the document back-end, or code in multiple places saves the same document. I've used the same method of passing the datasource down to the custom control, but that may just be because that was what I saw on a blog.
This question covncerns my lack of understanding of how to use the core data undo manager and how to restore a NSManagedObject to its state before editing was done.
I am just learning my way around Core Data. I have my NSManagedObject classes set up with their dynamic accessors. I perform a fetch that returns several NSManagedObject entity results. Content from each of these entity results (first name, last name) get put into a table view, and then the user picks one out of the table for detailed view and then editing.
The detail view controller receives a pointer to the selected NSManagedObject entity. As the user edits the fields, the corresponding property value in the NSManagedObject entity is updated. This seemed like the cleanest way to manage these changes.
Now, rather than committing the changes using save, I want to provide a cancel-editing feature that rolls back to what is in the data base for that entity. I really only want to restore the one entity and not perform the entire refetch.
I tried rollback and I tried NSUndoManager (with beginUndoGrouping and endUndoGrouping), and that is not working. I don't think I understand what rollback is really supposed to do.
But in any case, I still want to restore the property values in just that single entity (taking the lazy approach to only fetch what is needed, which is the one entity) so that my detail view controller can refill its view with the correct information. Right now it is using the NSManagedObject entity values, which contain the edited values, which were cancelled.
I suppose I could just start the edit process by creating a copy of the NSManagedObject. If the cancel-editing button is pressed, I could copy it back into the original. (I might even be able to just replace the original with the copy by moving the pointer. But since the pointer has actually been passed through several objects, I'm not sure how to manage the retain number on the copy.)
Does anyone have any other suggestions?
Thanks
Using rollback should accomplish what you want and I'm not sure what it doesn't. It is probably an implementation detail error.
You can find the specific managed object/s that were updated but not yet saved by calling the context's updatedObjects.
I'm designing my first project using Core Data (for iPhone) and Im having some issues that might be related with my design approach.
I'm doing an application that allows the user to create an Order (let's say for a restaurant).
I'm using the graphic designer to model my persistence object (i.e. OrdeMO). I add MO to the ead of each name to indicate its a Managed Object.
I use XCode to create the Managed Object Class automatically.
I have created some "DAO" classes that allows you to search or create a new object in the Managed Context.
Now to my problem.
I want to create an OrderMO object to store the order the user is creating, BUT I don't want it to be part of the context until the user actually places it.
I tried creating the object with [OrderMO alloc] but the object I get is "incomplete" and when I try to set any of its attribute I get an error.
I'm assuming the problem is that I need to create the order IN the context in order to use it. Is that so?
I have considered various options:
Create the object in the context and the user rollback if the user discards the order. The problem is that the user might save other context object during the process (like his prefs) so this doesn't work. Is there a way to create the object "inside a separate transaction" of sorts?
Create a wrapper object that will hold the same data as the MO, and then only create the MO when the user place the order. The downside of this is that I have to maintain a new class.
Create an attribute in the MO, such as "placed", and use to filter my searches in the context. The problem with this one is that I will end up with "trash" objects in the domain (i.e. unplaced orders) and I will have to do some cleanup from time to time...
Do I have any other choice?
Any suggestion is appreciated.
Thanks (for reading this long post!)
Gonso
You should create the OrderMO object in the managed object context and then delete it if the user decides not to place the order.
If the context is saved before the object is deleted, the "trash" object will be deleted from the persistent store on the next save (if the context wasn't saved, the "trash" object will never be saved to the persistent store).
The flag to determine if the order was placed or not does not have to live in the OrderMO object as you suggest in option 3. It could be in the view controller that is tracking the order(s) that are being edited. And, again, you won't have "trash" objects because they will have been deleted.