我正在完成迈克尔哈特尔教程,并且在登记工作时遇到了麻烦。
不是通过电子邮件进行ID,而是通过用户名工作。
注册和唱歌都很好,但我的退出会导致错误:
ActiveRecord::RecordNotFound in UsersController#show
Couldn't find User with username = signout
app/controllers/users_controller.rb:9:in `show'
为什么在show方法中查看users_controller?它为什么要这样称呼?它应该是调用会话控制器的删除方法,对吗?
违规第9行是:
8 def show
9 @user = User.find_by_username!(params[:username])
10 end
我不明白传递参数的位置(在哪里和哪些)导致它认为“注销”==用户名,而不是通过用户名和路由到session#destroy
。我怎么诊断这个?我可以在Rails控制台中输入什么来找出params中当前包含的内容?
更新
当我立即尝试时,我认为下面的解决方案有效,但问题刚刚从一条错误消息更改为另一条错误消息。我按照建议移动了路线,但仍然在
Request Parameters: {"username"=>"signout"}
这次它位于我的
`Users#show model: users/show.html.erb where line #1 raised:
undefined method username' for nil:NilClass
Extracted source (around line #1):
1: <\h2><%= @user.username %><\/h2>
2:
3: <!--
4:`
以下是我的routes.rb文件的内容:
match 'signup', to: 'users#new'
match 'signin', to: 'sessions#new'
match 'signout', to: 'sessions#destroy', via: 'delete'
resources :sessions, only: [:new, :create, :destroy]
match "/:username" => "users#show", via: "get"
resources :users
答案 0 :(得分:3)
我猜你有一条看起来像这样的路线:
get "/users/signout" => "sessions#destroy"
在此之前,您可能有一行如下所示:
get "/users/:username" => "users#show"
问题是,到/users/signout
的路由将与/users/:username
匹配,并将您的请求发送到show
的{{1}}操作,将UsersController
设置为{ {1}}。然后,您正在调用params[:username]
您需要将"signout"
路径置于<{1}}行之上,以便在User.find_by_username!("signout")
路线之前匹配。请记住,Rails停止尝试在 first 中找到匹配请求URI的匹配路由。您的更通用的外卡路线必须在之后出现更具体的可能重叠的路线。
您的/users/signout
路由需要HTTP DELETE请求,该请求通过带有/users/:username
参数的POST请求进行模拟。
为了匹配此路线,您需要使用表单或/users/:username
发出DELETE请求:
signout
销毁会话(在我看来)是一种特殊情况,您应该接受任何类型的HTTP请求。用户应该能够在其地址栏中键入_method=delete
或button_to
并通过GET请求销毁其会话。我强烈建议您删除button_to "Signout", signout_path, :method => :delete
并使用以下内容:
/logout
相反,您对/signout
和via: :delete
路由过于宽容,这些路由应特别使用GET和POST请求,并路由到match 'signout' => 'sessions#destroy'
和signup
个操作而不是采取同样的行动。
signin
我可以在Rails控制台中输入什么来查找params中当前包含的内容?
无。您无法通过Rails控制台检查new
哈希值,因为没有请求。您可以通过添加create
来检查日志文件,也可以在浏览器中将其提升为错误消息:get 'signup' => 'users#new'
post 'signin' => 'sessions#create'
。
答案 1 :(得分:1)
我也遇到了这个问题,meagar提到的修复程序并没有解决它。我的问题实际上源于JavaScript和链接中使用的DELETE
方法。显然,没有JavaScript的帮助,浏览器实际上不支持DELETE
请求。
要重现,只需关闭JavaScript并尝试使用一个使用此请求的链接,您会发现它使用GET
请求而不是指定的DELETE
。最终我需要包含需要rails.js
(或我的jquery-ujs
)的application.js来解决这个问题。