I want to be able to utilize the acts_as_state_machine transition methods which are auto-generated (e.g. event!).. but I don't want it to save right away. I'm updating the state as part of another set of operations, and so I don't want to be doing double saves.
Is there any way to trigger these event methods without a save right afterward?
By looking at acts_as_state_machine's code (line 65) I found that it is defining event-methods without a bang too. This will update the state internally in the object without storing it to the database. Hope that helps :-)
Related
I have a status field that needs to be updated to expired if the status is new and has passed a certain period of time.
Is there any issue with doing a save inside the after_find callback to update the record when it is loaded? Is there any other more appropriate callback for this?
There's no inherent issue with it, it will work. after_find is called anytime an existing record is instantiated. save inserts the attributes into the database, but doesn't re-instantiate the object, so you don't have to worry about unwanted recursion by calling save inside that callback. A similar callback would be after_initialize, the only difference being that after_initialize is called on new objects as well. after_find would be more appropriate.
Whether or not it's the best approach to the problem though is debatable. It's probably the easiest and quickest to set up. But you're relying on objects to be instantiated by your program for data integrity. What if you need to do a database dump? Sergio's suggestion is probably a better approach overall.
What I normally do is have a periodic background job (sidekiq/delayed_job or the like) that will find all freshly-expired records and update their flag. Much less surprising than a write in an after_find callback.
Something to think about: suppose that you load 100 records for showing in a view and find all of them expired. So instead of 1 query, you perform 101 query (one select and 100 updates). It directly affects page load time and it gets worse the more records you load at once. Whereas in my proposed approach it's only two queries, one of them out-of-band mass-update, not affecting page load at all.
I'm curious how exactly those callbacks work. If i initialize an object, and then use method save to throw it into my database, will before_create callback work?
Similar thing with before_save. is it called literally only before function save is being used, or will it be triggered also in case of using create method?
before_save will be triggered before you save a record. It doesn't matter whether you're creating or updating a record, your callback will be triggered. So, yes, it will also be triggered when you use the create method.
before_create is only triggered before creating a record, not before updating a record.
There is also before_update, which is only triggered before updating, but not before creating.
This doesn't depend on which method you use, it depends on whether the record was persisted before or not. In other words, it depends on whether you're updating or creating a record.
http://api.rubyonrails.org/v4.1.1/classes/ActiveRecord/Callbacks.html this url will help you find right answer for you. On this url you can also find the sequence for call back. Hope it helps you.
I often have a UITableViewController with an edit button, which I like to disable when there are no rows in the table. To keep this in sync, I enable/disable the button every time something happens that might update its dataSource - adding the first row, deleting the last row, in viewDidLoad, etc. Whenever I add some new functionality that can affect the contents of the table, I have to remember to incorporate this logic.
Is there some delegate of the UITableView that I can use to simplify this? A way to know whenever the table (or it's dataSource) is modified, where I can check the number of items in the dataSource and enable/disable accordingly.
Alternatively, any other approaches would be welcomed.
You are the data source. So you do know whenever the data source changes, if you care to know. In other words, the reason you're having this problem is that you're treating the model (in the model-view-controller architecture) as an alien being. Instead, treat the model as something of your own. Take charge of your model. For example, is the model an array? Then wrap it in a class of your own, to which all commands to change the array must be given. That way, it can emit a notification whenever it is told to change the array.
It is also possible under certain circumstances to use Key-Value Observing to get notified when something changes, and you could look into it, but with primitives like arrays and dictionaries it is possible that this will be more trouble than it's worth. Again, you're likely to be happier wrapping your model storage in your own class, whose observability via KVO you can manage yourself.
I have a somewhat complex data model in my iPad application (an OpenGL drawing app), and I'm working on implementing undo/redo functionality. I like the fact that Core Data will undo data model changes for free, but I don't know if the built-in functionality will be sufficient for me.
I have seen lots of examples of undo/redo being implemented in drawing apps, however they generally do the following:
Tell the managed object context to undo.
Redraw everything on the page from the changed data model.
This is horribly inefficient - in my app I need to be able to perform an action to undo based on the particular object that is being 'undone', and often this means refreshing only part of the canvas.
So my question is this: can I register my own undo operations and use that in conjunction with the built-in undos? For example, say I do the following when the user draws a line:
- (void)drawLineFromPoint:(CGPoint)startPoint toPoint:(CGPoint)endPoint
{
// Register the undo operation.
[[[managedObjectContext undoManager] prepareWithInvocationTarget:self]
removeObjectWithIndex:nextObjectIndex];
// Draw the line object.
[self drawLineObjectWithIndex:nextObjectIndex fromPoint:startPoint toPoint:endPoint];
// Save the new object to the data model.
[MyCoreDataHelper saveLineObjectWithIndex:nextObjectIndex fromPoint:startPoint toPoint:endPoint];
nextObjectIndex++;
}
When I come to undo this action, will the invocation be fired and the model changed appropriately? Or does this situation require that I abandon the built-in managed object context undo system and roll my own using just the NSUndoManager, including deleting and editing the data model myself? Unless I can tell what the built-in undo/redo is actually undoing, it looks like this could get horribly messy and complicated...
Edit: I suspect (if the idea above was to work) I would need to wrap it into an undo group, so that my registered undo operation would be grouped with the data model changes?
Another Edit: Also, can I guarantee the order in which undo actions will be carried out? In other words, if I call undo after the core data changes are saved and my undo action is registered, can I be sure that a deleted entity will be reinstated before my undo action is called?
Do you know then if it is possible to identify what data was changed from the undo?
Why don't you check out the notifications for NSManagedObjectContext (Apple Docs)
Specifically look at the notification's userInfo with the keys NSInsertedObjectsKey, NSUpdatedObjectsKey, and NSDeletedObjectsKey.
Also, can I guarantee the order in which undo actions will be carried out?
Well, undo works via stack (last in, first out), so you "should" be able to trace your steps. Obviously you have to be very specific in the order you register your undos if you want things to unfold correctly. A few lines of code that help me trace the undo stack just to see what is behind the veil of mystery:
id undoStack, redoStack;
object_getInstanceVariable(undoManager, "_undoStack", &undoStack);
object_getInstanceVariable(undoManager, "_redoStack", &redoStack);
NSLog(#"%#", [undoStack description]);
NSLog(#"%#", [redoStack description]);
(Props to this site for the above code)
Use the flyweight structure. It is generally used for undo/redo operations. What you're asking requires you to do this yourself.
Flyweights can store as much data as you want, and you can remove them from your undo sequence whenever you want. Your flyweights, for example, could store the pixel data before each edit was made. This would take large amounts of memory, but you could easily undo something without redrawing the entire scene.
What do you think about this programming practice:
- I need to execute one transaction at first form and after that to force some updates that are placed at another form (for each item that is shown at another form). I.e. it would be like show that form and click at some button. Because it is mandatory to execute these functionalities from second form, I thought to do it without showing second form. Is that good programming practice or you have some other recommendation?
Also, is it enough just to set property> Visible:=False before ShowModal for the second form or I need to do some other actions?
Well, it's unusual to have a form that you don't show. Normally you separate your business logic from the UI.
To answer your question, I don't think you need to call ShowModal at all. Just define a method on the form class and call that. Ultimately forms are just Delphi objects and you can use them as such. If you don't want to show them, don't call ShowModal or Show.
Second question first: Setting Visible := False is of no benefit because the point of all ShowXXX methods is to make the form visible. As David says, you could perform the actions without calling Show at all, provided of course your form doesn't rely on any OnActivate or OnShow code in order to do it's job properly.
As for whether this is a good idea, I say no!
As I've already pointed out there is a concern you have to watch out for. I.e. that currently (or even due to maintenance at some point in the future) your form relies on being visible to do its job properly.
Of course, you could work around that by letting the form flicker open, and be programatically closed. Clearly an aesthetically poor choice.
Not to mention the problems of getting it right. You'll end up writing a bunch of patch-work code to wrap the form so that it can do what you need to do, when you should rather do the following...
Correct Approach
Your form is currently doing at least 2 distinct things:
Visual UI control (call it A)
and "mandatory functionalities" (call it B)
It doesn't matter much whether B is doing validation rules, extra processing, or whatever.
B is a process that does not require user interaction.
Therefore, you need to:
Copy B into a non-UI location (either a simple unit with a custom object or a data module). Call it B*
Modify the form to call B* instead of using B.
Test that your form still behaves correctly.
Delete B
And now you can have your new form call B* instead.
The above approach will save you huge headaches in the future.