Rails会话找不到用户名为= signout的用户;为什么用户控制器在寻找它?

时间:2012-07-17 19:31:26

标签: ruby-on-rails-3 session activerecord controller

我正在完成迈克尔哈特尔教程,并且在登记工作时遇到了麻烦。

不是通过电子邮件进行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

2 个答案:

答案 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的匹配路由。您的更通用的外卡路线必须在之后出现更具体的可能重叠的路线。


RE:您的更新

您的/users/signout路由需要HTTP DELETE请求,该请求通过带有/users/:username参数的POST请求进行模拟。

为了匹配此路线,您需要使用表单或/users/:username发出DELETE请求:

signout

销毁会话(在我看来)是一种特殊情况,您应该接受任何类型的HTTP请求。用户应该能够在其地址栏中键入_method=deletebutton_to并通过GET请求销毁其会话。我强烈建议您删除button_to "Signout", signout_path, :method => :delete 并使用以下内容:

/logout

相反,您对/signoutvia: :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来解决这个问题。