我有两个控制器:VendorsController和ServicesController。供应商有服务,因此我创建了嵌套路由:
#config/routes.rb
Rails.application.routes.draw do
devise_for :users
root "static_pages#index"
get 'start', to: 'static_pages#start'
resources :vendors do
resources :services
end
end
服务列在供应商显示页面上,因此我希望拥有供应商页面的用户能够删除服务(所有这些都来自供应商显示页面)。这是我在服务控制器中的代码:
#services_controller.rb
class ServicesController < ApplicationController
before_action :authenticate_user!
# some more code
def destroy
@vendor = Vendor.find_by_id(params[:vendor_id])
@service = Service.find_by_id(params[:id])
if @service.user == current_user
@service.destroy
redirect_to vendor_path(@vendor), notice: "The service has been deleted."
else
return render text: 'Not Allowed', status: :forbidden
end
end
end
在vendor / show.html.erb中:
<% current_vendor.services.each do |service| %>
<% if current_vendor.user == current_user %>
<%= link_to "Edit Service", edit_vendor_service_path(service), class: 'btn btn-primary float-right'%>
<%= link_to "Delete Service", vendor_service_path(current_vendor), method: :delete, data: {confirm: 'Are you sure? This action cannot be reversed.'}, class: 'btn btn-danger float-right'%>
<% end %>
<% end %>
请注意,current_vendor是一个帮助方法。问题是这段代码在我的rspec测试套件中传递,但在实践中,我得到错误“ServicesController中的NoMethodError#destroy。未定义的方法`用户'为nil:NilClass”。在使用pry进行摆弄之后,我意识到我可以让它在实践中工作的唯一方法是将我的Services控制器中的destroy方法更改为:
def destroy
@vendor = Vendor.find_by_id(params[:id])
@service = Service.find_by_id(params[:vendor_id])
if @service.user == current_user
@service.destroy
redirect_to vendor_path(@vendor), notice: "The service has been deleted."
else
return render text: 'Not Allowed', status: :forbidden
end
end
一旦我这样做,当然我的rspec测试失败了。这显然没有意义,但我无法弄清楚我哪里出错了。谁能指出我的错误?