简体   繁体   中英

Rails DELETE http method renders page

I am trying to add a delete functionality to my model. This is what I've come up with, but even though I don't need to render the page to delete something, Rails renders and couldn't find the file for "delete.html.erb"

I am using Ruby 2.0dev and Rails 4.0

My delete link:

<%= link_to "Delete", reservation_delete_path(item), :class => "btn btn-small btn-danger", method: :delete, data: {confirm: 'Are you sure?'} %></td>

My routes file:

match 'reservations/delete/:id' => 'reservations#delete', via: :delete, :as => 'reservation_delete'

My Controller:

def delete
  @current = Reservations.find(params[:id])
  if current_user
    if @current.user_id == current_user.id
      @current.destroy!
      redirect_to reservations_path
    else
      redirect_to reservations_path
    end
  else
    redirect_to reservations_path
  end
end

There is no need to duplicate the redirect 3 times for each condition. You can simplify your delete method:

def delete
  @current = Reservations.find(params[:id])

  if current_user && @current.user_id == current_user.id
    @current.destroy!
  end

  redirect_to reservations_path
end

In your question, if current_user isn't available, you have no redirect, and so an implicit render is being run.

Your setup is not idiomatic, and there's code you didn't include, so anything could be going wrong. For example, that can't be your whole routes file; there's nothing specifying an index/show/edit/whatever page where your delete button would be. Another example: your action is named delete instead of destroy . Anyway I can show you an example that works and is much more canonical:

models/reservation.rb:

class Reservation < ActiveRecord::Base
end

controllers/reservations_controller.rb:

class ReservationsController < ApplicationController
  def index
    @reservations = Reservation.all
  end

  def destroy
    @reservation = Reservation.find(params[:id])
    @reservation.destroy

    redirect_to reservations_url
  end
end

views/reservations/index.html.erb:

<% @reservations.each do |reservation| %>
  <%= link_to 'Destroy', reservation, method: :delete, data: { confirm: 'Are you sure?' } %>
<% end %>

(this will literally only show links for deleting corresponding reservations... you'll have to stick <%= reservation.name %> or whatever in there if you want to see more info)

config/routes.rb:

Howdy::Application.routes.draw do
  resources :reservations, only: [:index, :destroy]
  root 'reservations#index'
end

(my app name is howdy)

You have some user auth going on, so add that accordingly. If you're inheriting from a controller that does special user-auth stuff before even hitting the action, that might be why it's trying to render delete.html.erb

看起来你错过了那些重定向的返回,这实际上导致Rails执行重定向尝试渲染视图。

return redirect_to reservations_path

Two things:

The delete (destroy) action is part of resources when you specify it in the routes file. To do this the "rails" way, you might consider having your routes file look more like:

resources: :reservations, only: [:delete]

... then having the delete link be more like:

<%= link_to 'Delete', delete_reservation_path(item), :class => 'btn btn-small btn-danger', method: :delete, data: {confirm: 'Are you sure?'} %>

... and then in your controller you can:

def destroy
  @current = Reservations.find(params[:id])
  if current_user
    if @current.user_id == current_user.id
      @current.destroy!
      redirect_to reservations_path
    else
      redirect_to reservations_path
    end
  else
    redirect_to reservations_path
  end
end

... or you could actually create an rjs template for the delete action to do some fancy javascript work, or you could simply render the view for the index action (faster load the redirecting).

My recommendation when you start putting up && gates is to check to see if there is an existing solution. In this case you're probably looking for the functionality that is available in the CanCan gem.

CanCan

basically you load_and_authorize your users before the controller action and check them through an Ability model. You also get view helpers like

if can? :destroy, reservation 
  ... do awesome stuff here ...

This will be a far better solution over the long run.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM