我正在尝试向我的模型添加删除功能。这就是我想出的,但即使我不需要渲染页面来删除某些内容,Rails 也会渲染并且找不到"delete.html.erb"的文件
我正在使用Ruby 2.0dev和Rails 4.0
我的删除链接:
<%= link_to "Delete", reservation_delete_path(item), :class => "btn btn-small btn-danger", method: :delete, data: {confirm: 'Are you sure?'} %></td>
我的路由文件:
match 'reservations/delete/:id' => 'reservations#delete', via: :delete, :as => 'reservation_delete'
我的控制器:
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
无需为每个条件复制 3 次重定向。您可以简化删除方法:
def delete
@current = Reservations.find(params[:id])
if current_user && @current.user_id == current_user.id
@current.destroy!
end
redirect_to reservations_path
end
在您的问题中,如果current_user
不可用,则您没有重定向,因此正在运行隐式渲染。
您的设置不是惯用语,并且您没有包含代码,因此可能会出现任何问题。例如,这不能是整个路由文件;没有指定索引/显示/编辑/删除按钮所在的任何页面。另一个示例:您的操作被命名为 delete
而不是 destroy
。无论如何,我可以向您展示一个有效且更规范的示例:
models/reservation.rb:
class Reservation < ActiveRecord::Base
end
控制器/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 %>
(这实际上只会显示删除相应预订的链接......如果你想看到更多信息,你必须把<%= reservation.name %>
或其他任何东西粘在那里)
config/routes.rb:
Howdy::Application.routes.draw do
resources :reservations, only: [:index, :destroy]
root 'reservations#index'
end
(我的应用名称是 Howdy)
您正在进行一些用户身份验证,因此请相应地添加它。如果您继承自一个在点击操作之前执行特殊用户身份验证操作的控制器,这可能就是它尝试渲染delete.html.erb
的原因
看起来您缺少这些重定向的返回,这实际上导致 Rails 执行重定向并尝试呈现视图。
return redirect_to reservations_path
两件事:
删除(销毁)操作在路由文件中指定时是资源的一部分。要以"rails"方式执行此操作,您可以考虑让路由文件看起来更像:
resources: :reservations, only: [:delete]
。然后让删除链接更像:
<%= link_to 'Delete', delete_reservation_path(item), :class => 'btn btn-small btn-danger', method: :delete, data: {confirm: 'Are you sure?'} %>
。然后在控制器中,您可以:
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
。或者,您实际上可以为删除操作创建一个 RJS 模板来执行一些花哨的 JavaScript 工作,或者您可以简单地为索引操作呈现视图(更快地加载重定向)。
当你开始安装&&gates时,我的建议是检查是否有现有的解决方案。在这种情况下,您可能正在寻找CanCanCan珠宝中可用的功能。
康康舞
基本上,您在控制器操作之前load_and_authorize用户,并通过能力模型检查他们。您还可以获得视图助手,例如
if can? :destroy, reservation
... do awesome stuff here ...
从长远来看,这将是一个更好的解决方案。