Inter row dependencies in data

Hi there, I want to create a rails app to track vehicle mileage. I figure this would be a good first project to learn how to use rails. But I'm hitting a snag.

I want to have a model for refueling events. They'd have a date, odometer reading, gallons, cost, etc. But the problem is that for each event there is a number of miles elapsed since the previous event. (This is the miles travelled) I don't want to force the user to do that math, I just want to enter the odometer reading at each event.

I can think of two ways to handle this, and I don't like either. I'm hoping to get some feedback on the "correct" way to do this.

Possibility one: Have an elapsed miles property on the event, but not stored in the data base. Then whenever a collection of events is loaded from the db, a helper method iterates over the events, and calculates the correct elapsed miles for each one.

- Seems like I'd have to do this iteration a lot. And I want to be DRY

Possibility two: Store the elapsed miles in the database. When a new event is created, attempt to find the previous event (it'll be the one with the highest odometer reading) and set the elapsed miles from the current - previous odometer settings.

- Assumes I'd have to enter the events in order, and what happens when a user edits an event somewhere in the middle, and changes the odometer setting.

Admittedly, I'm a noob and I come from a java background, so my brain hurts as I try to transition into the ruby/rails way of thinking. Any suggestions will be helpful and educational.

Thanks, John Schank

Store the elapsed miles of the last trip as well as the odometer reading... since many cars have an elapsed miles since that little nobbly thing was pressed AND an odometer. If they don't enter the elapsed mileage, find the one with the highest odometer and then do the math in a before_save. You don't need to enter them in any order, just do a Trip.find(:first, :order => "odometer_reading DESC") and that'll find the last one with the highest reading.

When a user updates one in the middle, get it to change the elapsed mileage on that one, as well as all future events because they could've all changed. This may be a costly procedure, however.

Thanks for the reply. I like the suggestion, what I meant about out of order... Suppose I have a accumulated a few gas station receipts, and I want to enter them in bulk. In such a case, the entries might not be added in odometer order. It is the same problem as when a user makes a mistake, then goes back and edits an entry somewhere in the middle of the entries. If that edit changes the odometer reading. (i.e. the first time it was entered, the reading had some transposed digits or something) Then I would need to propagate that edit forward through all subsequent entries.

Also, suppose the user enters both an odometer reading, and a trip reading. But they don't agree. (i.e. the trip was reset earlier by mistake or similar)

It is these reasons why I lean toward not storing the trip distance. And just calculating it. I was hoping there would be a mechanism, like a before_filter, where I could inject my iteration and calculation once.

If they don't agree then there's been a mistake made somewhere... maybe notify them of this and still add it in? Not sure.

I did mention before you could use a before_save to do all this calculation in your model.

ahh, right you are. I totally missed the before save. (But my subconscious must not have missed it because I mentioned the filter...heh must be bed time)

Is there an advantage to saving it? I mean couldn't I do some math in something like an "after_read" if that exists? Then my model has the info it needs. The model should be correct. And I don't write any potentially conflicting data, in the case where data is entered out of order. Also, if a user edits a previous odometer reading. Wouldn't my next read of the data re-calculate in the (possibly mythical) "after_read"?

Thanks again, John

I think there may be an after_find.