Git Product home page Git Product logo

delete-forms-rails's Introduction

DELETE Forms and Requests

So far, we've worked with three pieces of the CRUD puzzle:

  • Creating records, using HTTP POST requests.
  • Reading records, using HTTP GET requests.
  • Updating records, using HTTP PATCH requests.

One piece remains:

  • Deleting records, using HTTP DELETE requests.

But, all is not well in Browsertown. In many cases, sending a request with the PATCH or DELETE method will not work. In this lesson, we'll focus on DELETE, but many of the same issues arise with PATCH requests, as well.

Why? What can we do as a workaround?

Objectives

After this lesson, you'll be able to...

  • Draw a delete route mapping to a #destroy() action
  • Explain the problem with submitting delete requests
  • Use form_tag to build a delete form for an object
  • Build a #destroy() action that finds the instance, destroys it, and redirects to the index action
  • Use link_to and button_to :method => :delete to destroy an object without a form

Ignorance is bliss

Before we dive into the problem with DELETE (and PATCH) requests, let's proceed as if we were none the wiser, setting up our route and form as usual:

# config/routes.rb

delete '/people/:id', to: 'people#destroy', as:'person'
# app/views/people/show.html.erb

<h2><%= @person.name %></h2>
<%= @person.email %>
<%= form_tag person_path(@person.id), method: "delete" do %>
  <%= submit_tag "Delete #{@person.name}" %>
<% end %>

But, wait a minute... there's something weird about the output we get:

<h2>Caligula</h2>
[email protected]
<form accept-charset="UTF-8" action="/people/1" method="post">
  <input name="_method" type="hidden" value="delete" />
  <input name="utf8" type="hidden" value="&#x2713;" />
  <input name="authenticity_token" type="hidden" value="f755bb0ed134b76c432144748a6d4b7a7ddf2b71" />
  <input name="commit" type="submit" value="Delete Caligula" />
</form>

Enhance!

<form accept-charset="UTF-8" action="/people/1" method="**post**">
  <input name="_method" type="hidden" value="**delete**" />

What's going on? Why the extra input?

Programming is hard

Web developers love to be on the cutting edge. We hoover up new tools and techniques and aren't afraid of breaking a few million eggs to figure out that we actually have no idea how to make an omelette. Projects like Rails themselves are a product of this incredible devotion to progress and automation.

Browser and server developers are the yin to the web developers' yang. These are the people who own and maintain the tools themselves: Internet Explorer, Firefox, Chrome, Apache, and so on.

When a web developer makes a mistake, it might affect the users of their site.

When a browser or server developer makes a mistake, it might affect over a billion people!

Because of this, browser/server developers have to go slow. Really slow. And they have to resist the urge to release "duct tape" solutions because duct tape doesn't scale to a billion users!

This means that, sometimes, incomplete solutions can remain in place for years, or even decades, while the maintainers go back and forth trying to find a better approach that won't open an eldritch portal to Bosch's Garden of Earthly Delights.

What's all this have to do with DELETE requests?

As of HTML5, forms officially do not support DELETE and PATCH for their methods.

There's no short and sweet answer to explain this. If you want to dive deep and understand as much as possible about the decisions that went into it, you can read more on this illuminating StackExchange post, but, for the purposes of succinct explanation, you can always stick with the tried and true "for historical reasons."

What you're seeing in the above #form_tag() behavior is a workaround implemented for us by Rails itself. With this in mind, we get the best of both worlds:

  • We get to be good HTTP-abiding citizens who use the correct request methods for their corresponding goals (GET for read, PATCH for update, and so on).
  • We get to maintain our sanity and not worry about W3C drama while writing views.

That's great. Can we actually delete something now?

Thus enlightened, we can (finally) proceed with our original goal:

# app/controllers/people_controller.rb

  def destroy
    Person.find(params[:id]).destroy
    redirect_to people_url
  end

Nothing too special happening here except for a bit of method-chaining to immediately destroy the found instance.

Fancy JavaScript Helper

As shown, you have to go to a user's show page to delete them. What if we want an admin control panel where users can be deleted from a list?

<!-- app/views/people/index.html.erb //-->

<% @people.each do |person| %>
<div class="person">
  <span><%= person.name %></span>
  <%= link_to "Delete", person, method: :delete, data: { confirm: "Really?" } %>
</div>
<% end %>

link_to is a method of UrlHelper that has a number of convenient features.

The HTML generated by that call to link_to looks like this:

<a data-confirm="Really?" rel="nofollow" data-method="delete" href="/people/1">Delete</a>

The data-confirm attribute and the data-method attribute rely on some JavaScript built into Rails.

data-method will "submit" a DELETE request as if a form had been submitted. It will use GET (the default method used by all browsers for HTML links) if the user has JavaScript disabled.

data-confirm pops up a confirmation window before the link is followed, allowing the user to make sure they're ready to delete someone forever (what a decision!).

Use button_to

A slight variation from the link_to method described above is using button_to to send a delete request.

Says the documentation:

[button_to] Generates a form containing a single button that submits to the URL created by the set of options.

So while we taught link_to first, Rails thinks that button_to is a safer tool for representing delete requests. Interesting! The button_to helper works very similarly to link_to:

<%= button_to "Delete Image", image_path(@image), method: :delete %>

As you can read in the documentation, or guess thanks to Ruby's simple syntax, the first argument is the button text; the second argument is an expression of a route, and method is used to tell the form to send its payload as an HTTP DELETE action.

delete-forms-rails's People

Contributors

annjohn avatar aviflombaum avatar bhollan avatar changemewtf avatar curiositypaths avatar ihollander avatar jmburges avatar maxwellbenton avatar mendelb avatar rrcobb avatar sbal13 avatar sdcrouse avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

delete-forms-rails's Issues

Misplaced lesson?

The Readme suggests that readers do not yet know how to update in Rails, leading me to believe that this lesson was intended to go in the preceding CRUD unit. If this is the correct placement for the lesson, perhaps the Readme might explain the connection between #destroy and Validations, or there could be a note in the CRUD section to let students know that they'll be learning how to delete later.

form_tag should have a "do"

Hi, this example in the Delete forms lab, the <%= form_tag %> should have a do at the end
source: https://stackoverflow.com/questions/27478508/syntax-error-unexpected-keyword-ensure-expecting-end-of-input-with-rails

original:

<h2><%= @person.name %></h2>
<%= @person.email %>
<%= form_tag people_path(@person.id), method: "delete" %>
  <%= submit_tag "Delete #{@person.name}" %>
<% end %>

updated:

<h2><%= @person.name %></h2>
<%= @person.email %>
<%= form_tag people_path(@person.id), method: "delete" do %>
  <%= submit_tag "Delete #{@person.name}" %>
<% end %>

Delete Forms Rails

Hello,

In this lesson, it mentions we will learn to:

  • Use link_to and button_to :method => :delete to destroy an object without a form

The link_to is explained in the lesson with the Javascript information, but the button_to option was not explained in the lesson.

Thanks!

This lesson is really unclear

I enjoyed the style and voice it was written in but the technical material was not clearly delivered. It's not clear what the relationship between the third and fourth code samples are in the "Ignorance is Bliss section", and the only frame of reference is the single word "enhance".

'form_tag' misses 'do'

This block of code will raise a syntax error:

image

should add a do to form_tag:

<%= form_tag people_path(@person.id), method: "delete" do %>

Issue in "Ignorance is bliss" section

Lines 5-7 in the first snippet of this section are as follows:
<%= form_tag people_path(@person.id), method: "delete" %>
<%= submit_tag "Delete #{@person.name}" %>
<% end %>

The end tag here will actually break this form_tag setup do to there not being a "do", and I believe you want to actually to pointing the form to "person_path(@person.id)".
This code will send a delete request to "/people.[id]" but we want it to send it to "/people/[id]".

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.