Non JavaScript dependent scaffolding solution for record deletion

Hello,

The generated scaffold relies on Javascript enabled to be able to
delete a record, which prevents anyone with JavasScript disabled to
delete it.

I've hacked a solution with a delete action in one of my projects,
which works nicely, and cleanly. Basically, the link still have
Javascript which will work if enabled, but the url of the link goes to
a delete action, with a form that confirms the user wants to delete
(instead of a Javascript prompt).

Only took 3 new controller lines, 6 new view lines, 1 changed view
line, and a route :member.

Is this something that people would like to see in Rails 3?

Regards
Kieran

I'd vote NO. Scaffolding isn't about providing a cross-browser solution with graceful degradation. It's about giving you a temporary structure you can lean your app against while building it. By the time you want to launch the app, scaffolding should be replaced by code you built yourself. I don't have anything against doing things the way you propose, but I'd rather scaffolding stay as minimal and simple as possible. Every line of code in the scaffolding bears a maintenance cost, and it seems better to keep it easy to upgrade than make it feature-complete for end-users.

Hey Josh.

Thanks for your comments.

I'd vote NO. Scaffolding isn't about providing a cross-browser solution with graceful degradation.

Perhaps not, but isn't it better to have applications that do and to
promote graceful degredation?

And even if the scaffolding doesn't get changed, the code to support a
delete action by default would still be a good thing, rather than
adding a collection to each resources route.

It's about giving you a temporary structure you can lean your app against while building it.

Most of my code still uses scaffolded controller code (only added
lines to it, didn't take away).

By the time you want to launch the app, scaffolding should be replaced by code you built yourself.

For the views and tests, sure. But the base of the model and
controllers likely stay the whole way through app development (at
least, this has been the case with a project I'm working on at the
moment).

I don't have anything against doing things the way you propose, but I'd rather scaffolding stay as minimal and simple as possible.

When it comes down to it, it's only 3 controller lines and a view
file.

Every line of code in the scaffolding bears a maintenance cost

Shouldn't be much though right? How often does the scaffolding code
change per release since 2.1?

Regards
Kieran

I think this is something that is always annoying.
Namely I have to reinvent a convention to handle this.

Something like "pre_delete" with a GET
- this is just a proper delete form
and "delete" with a DELETE
- this does the delete

but I think we deserve to have this baked into rails.

I think it'd be cool if;
GET /posts/delete mapped to the "pre-delete" action
DELETE /posts/delete mapped to the "delete action"

thereby,
with a "link_to "delete", :method => :delete"
you automatically fall back when javascript is disabled.

Boom.

I am in favor of a standard delete action, analagous to new and edit. I
can’t think of a good reason not to have it–it shows good practice and
isn’t exactly a new concept. We have new and edit as HTML precursor
actions for the POST and PUT verbs, why not delete as HTML precursor
for DELETE. One of the biggest wins of Rails is conventionality; when
you come into a new Rails app, you don’t have to wonder what the edit
action is called. Why not extend this to delete confirmation screens as
well?

– Yehuda

MatthewRudy wrote:

MatthewRudy wrote:


I think this is something that is always annoying.
Namely I have to reinvent a convention to handle this.
Something like "pre_delete" with a GET
- this is just a proper delete form
and "delete" with a DELETE
- this does the delete
but I think we deserve to have this baked into rails.
I think it'd be cool if;
GET /posts/delete mapped to the "pre-delete" action
DELETE /posts/delete mapped to the "delete action"

This doesn’t make sense. The normal HTTP convention would be:

DELETE /posts/1 to delete.

I like the idea of:

GET /posts/1/delete for a DELETE confirmation screen. You’d then have:

-1.

I am in favor of a standard delete action, analagous to new and edit. I
can't think of a good reason not to have it--it shows good practice and
isn't exactly a new concept.

It makes poor and slow UI.

We have new and edit as HTML precursor actions
for the POST and PUT verbs, why not delete as HTML precursor for DELETE. One
of the biggest wins of Rails is conventionality; when you come into a new
Rails app, you don't have to wonder what the edit action is called. Why not
extend this to delete confirmation screens as well?

When you edit/create - you don't just press one button. You enter a
good amount of data too. That's not true when you DELETE the record in
99.99% of the cases.

Pratik wrote:

-1.

+2

I am in favor of a standard delete action, analagous to new and edit. I
can't think of a good reason not to have it--it shows good practice and
isn't exactly a new concept.
It makes poor and slow UI.

Sure. Better than no UI, wouldn’t you say?

We have new and edit as HTML precursor actions
for the POST and PUT verbs, why not delete as HTML precursor for DELETE. One
of the biggest wins of Rails is conventionality; when you come into a new
Rails app, you don't have to wonder what the edit action is called. Why not
extend this to delete confirmation screens as well?
When you edit/create - you don't just press one button. You enter a
good amount of data too. That's not true when you DELETE the record in
99.99% of the cases.

Are you suggesting that we just put an inline small form with a submit
button to DELETE the record? I’d be ok with that, provided we’re not
worried about the lack of confirmation. Maybe gracefully degrading the
confirmation isn’t very important (after all, the functionality is
still available)?

– Yehuda

+1

We follow this pattern and I've often wished it was a standard resource action instead of cluttering up my routes file. To the UI concern, we enhance the links via javascript to do an immediate destroy where appropriate (just takes one attribute on the link once you have a little app-wide JS in place). It makes testing with cucumber/webrat easier and gives us a built-in solution for users without javascript.

I was just about to suggest that when I read the rest of the comments. +1 for the inline form

I like the idea of a small inline form for scaffolding. But I also
REALLY like the idea of a standard HTML-only approach that supports
confirmation: some resources are too important to delete without
confirmation (or better yet, a "review" of the consequences), and
counting on JavaScript is Bad.

+1 for GET /posts/1/delete
+1 for small inline form in scaffolding that DELETE /posts/1 (without
confirmation if deemed appropriate).

-Chris

I I agree that for the purposes of scaffolding, it should be an inline form. However, I think having map.resource(s) support GET /posts/1/delete by default would be a good idea; often a javascript popup isn't the best way to ask for confirmation

Toss in another favorable vote for an inline form with a submit for the DELETE action. This would be good as it (a) gracefully degrades on its own, and (b) clearly illustrates to the developer what code needs to be written to put the form together correctly in the future.

I view the confirmation alert as a “nice-to-have” feature but not necessary to the base scaffolding functionality. Perhaps that would be a reasonable case for inline javascript on the deletion form? Just enough to make it work out of the box and demonstrate what should be going on.

-Alex

+2

http://en.wikipedia.org/wiki/Dissociative_identity_disorder ?? You're
just one person, wake up :wink:

Are you suggesting that we just put an inline small form with a submit button to DELETE the record? I'd be ok with that, provided we're not worried about the > lack of confirmation. Maybe gracefully degrading the confirmation isn't very important (after all, the functionality is still available)?

No I'm not suggesting that. I'm not suggesting any change. You are.
And confirmation *is* important.

I understand the change you people are suggesting is desired in many
situations. However, it's very easy to add that and it does not belong
in scaffolding.

I like the delete GET for a confirmation page. However, if javascript
is enabled it should allow the bypass of this page.

+1 for using button_to instead of link_to.

And if submit_tag were to generate a <button> instead of an <input>
then +10000000000 :slight_smile:

-foca

Not sure I understand your position. The existing functionality where a JS dialogue appears requires the user to just press one button, and you’re saying that this is good UI, but having an HTML form appear requiring the user to press a button is not good UI?

Seems like precisely the same UI to me, just in two different forms and with the obvious latency for the non-JS user. As others have mentioned, surely a slower UI is better than no UI at all?

+1 for the GET request on a delete action to show a confirmation
dialog. Also if you send a DELETE call to this URL it could trigger
the destroy action directly. This way it conveniently degrades nicely
with javascript.

<%= link_to "Destroy", delete_item_path(item), :method
=> :delete, :confirm => "Are you sure?" %>

GET /items/1/delete # => maps to delete action with confirmation
screen
DELETE /items/1/delete # => maps to destroy action

If javascript is disabled it will fall back to a GET request and
therefore display a confirmation screen.

Having this defined by default in map.resources would be convenient
and won't get in the way if not used. Whether or not scaffolding takes
advantage of this I don't care.

Ryan

+1 for the GET request on a delete action to show a confirmation
dialog. Also if you send a DELETE call to this URL it could trigger
the destroy action directly. This way it conveniently degrades nicely
with javascript.

<%= link_to "Destroy", delete_item_path(item), :method
=> :delete, :confirm => "Are you sure?" %>

GET /items/1/delete # => maps to delete action with confirmation
screen
DELETE /items/1/delete # => maps to destroy action

If javascript is disabled it will fall back to a GET request and
therefore display a confirmation screen.

That's very tidy, +1 on that specific permutation.

I presume the idea would be to have DELETE /items/1 still mapping to destroy as well, for backwards compat (with a deprecation notice). If not - then -1 :slight_smile:

Having this defined by default in map.resources would be convenient
and won't get in the way if not used. Whether or not scaffolding takes
advantage of this I don't care.

I think if you make it like this then you need to have scaffolding support it - otherwise (I think) you'll get a missing template error when JS is disabled, which is untidy -> "Won't somebody PLEASE think of the newbs?!?"

+1 for scaffolding support.

Cheers,
Jason

I'd certainly hope there's not a deprecation notice - the 'DELETE /items/1/delete' is distinctly un-RESTful. The HTTP verb is sufficient - do we really want to be POSTing to /items/create and PUTting to /items/1/update (again)?

--Matt Jones