I think with a system based on identity maps, you have to assume that you're using the same object that others are, and hence there might be existing changes. In my mind, that gives you the choice to either do both updates (my preference) or neither, but not to do just one. I suppose you could justify doing just one *if* you could guarantee to make it seem as if that change had occurred before the other had seen the attribute you updated, so you effectively alter the sequence of changes.
But basically, if you have independent users of the object, you have a transaction isolation problem, and the possible courses of action have been well-studied. Clifford Heath. On 15/08/2009, at 6:00 PM, Dan Kubb (dkubb) wrote: > > Hi Everyone, > > I've got a scenario I wanted to get input on because I'm not sure what > the best approach is. > > This question is specifically for Resource#update, which currently > works like this: > > user = User.get(1) > user.update(:admin => true) > > The above code will fetch User 1, and then set the :admin flag to > true. Pretty simple and straight forward, very much like > Resource#update_attributes in 0.9.x, which is what it essentially > replaces. > > However, consider the following code: > > user = User.get(1) > user.name = 'John Doe' # change the user's name > > # ... > > user.update(:admin => true) > > Now, the question is: should the whole user object be saved, including > the :admin flag *and* the :name? Or should it just persist the :admin > flag, and not persist the :name attribute change? > > I'm not precisely sure what the best approach to this is. In a web > app, this will probably never be an issue since the general pattern is > to update the resource in one step. Either approach we decide on > probably won't affect web apps. However, I am trying to make sure it > acts in a consistent manner for other use-cases, taking into account > POLS. > > I'm sort of leaning towards explicitness in this case, although I am > not sure. I think it's a bit weird to have a method that persists an > object given some values, but also persists any existing changes too. > So calling Resource#update with specific attributes would only persist > those attributes and no others. Off the top of my head I can think of > one problem this causes: what if there's some validation rule that > says only the user "John Doe" can be an admin? In the above code, say > we run a validation on user prior to updating it, we'll see the name > as "John Doe" and the admin flag set to true.. however, the name would > not have been persisted while the admin would be true, putting the > persisted object in an invalid state. > > One primary principle in DM is that all persisted objects are assumed > to be valid. We can't be loading up all the associated objects to > make sure it's valid or not, you'd have to load up the entire object > graph to do that, so we have to assume once it's persisted it is > valid. In this case tho, it would be possible to persist an invalid > object, which is a big no-no. > > One work-around to this problem I can think of is temporarily stashing > previously changed attributes when executing Resource#update, > validating the object in it's persisted state, persisting it, and then > restoring the attributes from the stash. A bit icky, but it should be > trivial to implement. The problem I have with this is that I'm not > sure what side effects it'll have. There could be none, or there > could be some weird bugs caused by this. I don't want to introduce > any surprises in the API. > > What do you all think? > > -- > > Dan Kubb > (dkubb) > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "DataMapper" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/datamapper?hl=en -~----------~----~----~----~------~----~------~--~---
