如何为具有Devise的删除用户生成正常的URL,而不是具有格式的URL?

时间:2016-01-21 05:37:44

标签: ruby-on-rails ruby-on-rails-4 devise

在用户帐户的设置页面上,我想添加一个取消按钮。我一直存在的问题是,正常的事情是创建一个具有.format的网址。

这就是我的观点:

<%= link_to "Cancel my account", cancel_user_account_path(resource), data: { confirm: "Are you sure you want to cancel your account? All of your memories WILL be lost!" }, method: :delete, class: "btn left" %>

路线

delete "cancel", to: "users#destroy", as: :cancel_user_account

在我的rake routes中生成此内容:

cancel_user_account_path    DELETE  /cancel(.:format)   users#destroy

这就是我User#Destroy的样子:

  def destroy
    @user = User.find(params[:id])
    if @user.destroy
      redirect_to root_path, notice: "You have successfully cancelled your account."
    else
      redirect_to :back
    end    
  end

那是正常的。

但是这会继续生成此网址:http://localhost:3000/cancel.148

单击时会生成此错误:

Started DELETE "/cancel.148" for 127.0.0.1 at 2016-01-21 00:30:02 -0500
Processing by UsersController#destroy as 
  User Load (1.3ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 148  ORDER BY "users"."id" ASC LIMIT 1
  FamilyTree Load (1.0ms)  SELECT  "family_trees".* FROM "family_trees"  WHERE "family_trees"."user_id" = 148 LIMIT 1
  Node Load (1.6ms)  SELECT "nodes".* FROM "nodes"  WHERE "nodes"."family_tree_id" IN (150)
  Role Load (0.8ms)  SELECT "roles".* FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL)))  [["user_id", 148]]
Completed 404 Not Found in 23ms (ActiveRecord: 4.6ms)

ActiveRecord::RecordNotFound - Couldn't find User without an ID:

在我的错误页面中,我可以检查参数...这就是它随请求发送的内容:

Request parameters  
{"_method"=>"delete", "action"=>"destroy", "controller"=>"users", "format"=>"148"}

我不知道如何让它生成/cancel/148

我尝试了许多路线的排列,包括将它放在devise_for :user块中,如下所示:

  devise_scope :user do
    get "settings", to: "devise/registrations#edit"
    delete "logout", to: "devise/sessions#destroy"
    delete "cancel", to: "users#destroy", as: :cancel_user_account
  end

我甚至尝试使用设计似乎产生的其他路线:

edit_user_registration_path GET /users/edit(.:format)   registrations#edit
                            PATCH   /users(.:format)    registrations#update
                            PUT /users(.:format)    registrations#update
                            DELETE  /users(.:format)    registrations#destroy

但即使这样仍然会产生一个奇怪的路径:http://localhost:3000/users/edit.148,它会产生类似的错误:

ActiveRecord::RecordNotFound at /users/edit.148
Couldn't find User with 'id'=edit

这些是参数:

Request parameters  
{"_method"=>"delete", "action"=>"destroy", "controller"=>"users", "id"=>"edit", "format"=>"148"}

我做错了什么?

2 个答案:

答案 0 :(得分:1)

定义的路线不正确。

这将是:

enable-capieng

实际上,这个更短但足够(确保它不与其他路线冲突)

delete "/users/:id/cancel", to: "users#destroy", as: :cancel_user_account

答案 1 :(得分:1)

您正在将资源作为输入发送到cancel_user_account_path,其中只有格式参数,因此rails猜测您指的是要映射到格式的资源。你可以做两件事:

1-您可以明确告诉rails输入应该映射到的内容:

cancel_user_account_path(id: resource) #=> http://localhost:3000/cancel?id: 148

2-您可以在路线中添加id,以便rails将第一个输入映射到它:

delete "cancel/:id", to: "users#destroy", as: :cancel_user_account #=> http://localhost:3000/cancel/148

但是,以上两种情况在生产环境中都很危险。只要您期望用户ID作为输入,任何人都可以取消任何用户的帐户!实际上不通过/期望任何输入ID并更改控制器操作以使用current_user更安全:

def destroy
    if current_user.destroy
      redirect_to root_path, notice: "You have successfully cancelled your account."
    else
      redirect_to :back
    end    
end