On Tuesday, July 20, 2010 02:01:14 pm Jared Morgan wrote:
> I'm confused. I was under the impression that the only case in which
> save would not raise on error on failure is when validation fails

Digging around in the code a bit, this seems to be true.

> In this case, it's not the code that's
> the problem but rather user input. Right?

Not always.

For one, where is this assumption that every DM resource must be directly 
related to user input? As an example, say I have a logging class of some sort 
with a few required columns, and for whatever reason, I end up with a nil. 
Which would you rather have happen in this situation:

 - Exception is raised, the user gets a Fail Whale
 - Exception is raised, the user gets a stack trace
 - Exception is raised, caught, and logged without the user seeing a thing
 - Invalid state is caught and logged without the user seeing a thing
 - Invalid state is ignored, and this message SILENTLY SLIPS AWAY

Of these, I don't know about you, but the last is unacceptable to me. If I 
fail to catch an exception, worst case, the user gets a stacktrace. If I fail 
to make sure I saved, worst case, I LOSE DATA.

I apologize for the caps, but this is important, and I'm a bit surprised that 
there's even an argument about it.

It's not just logging, it's _any_ ancilliary data I might generate with code, 
rather than directly from HTTP. For example, I once had a User model and a 
separate Email model, so users could have multiple email addresses (but only 
one primary one). To keep things clean, I had an interface roughly like this:

class User
  attr_accessor :email
  belongs_to :primary_email, :model_name => 'Email'
  before :save do
    primary_email = Email.find_or_create_by_name email
    ...
  end
end

...roughly. The idea was to expose only a single email address to the user, 
but to delay verifying a new one until a confirmation email was sent.

Confirmation codes! That's a whole other model/table that no user should ever 
have to touch directly.

> At
> least in the case of validations causing the failure, I'd much rather
> not have to handle an exception

I'd suggest something like 'try_save', rather than 'save', if we were able to 
make breaking changes to the API at this point. (I don't know why I waited 
till post-1.0 to bring this up again...)

> (and I don't consider an end-user
> mistyping something an exceptional situation). Am I missing something?

Even in this case, DataMapper is used outside of full-stack frameworks like 
Rails. Say I've forgotten to add in any sort of validation. We're again stuck 
with something like this (pseudocode):

put '/foos/:id' do |id|
  obj = DataMapper.get id
  obj.update params[:whatever]
  redirect "/foos/#{id}", 303
end

Whoops. Yes, this was user input. No, it wasn't exceptional. But the user has 
no clue what happened or why -- the best they can hope for is to look very 
carefully at the resulting page to make sure it was updated correctly.

Now, I agree, it'd better if you can handle this sort of thing explicitly. But 
if you've already got the code in place to do that, it should be a relatively 
minor change to use a differently-named method, like 'try_save'. If you don't, 
and you're counting on yourself to always do something like:

put '/foos/:id' do |id|
  obj = DataMapper.get id
  obj.update params[:whatever] || return 'Save failed!'
  redirect "/foos/#{id}", 303
end

...you're just asking to lose data.

I think the place this annoys me the most is when I'm playing around in the 
console, and I want to type something like some_list.each(&:save) -- whoops, I 
have no idea if I did anything there.

-- 
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.

Reply via email to