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

Dissociative identity disorder - Wikipedia ?? 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