我是编程的绝对初学者(刚开始深入研究Ruby on Rails),这是我在StackOverflow上的第一篇文章,但我事先做了一个彻底的研究,没有一个类似问题的答案为我提供了我的解决方案问题
即,在Michael Hartl的“使用Rails学习Web开发”教程的第9.2.1节之后启动我的测试套件时,我收到了2次失败:
Failures:
1) Authentication authorization for non-signed-in users in the Users controller submitting to the update action
Failure/Error: before { patch user_path(user) }
ActionController::ParameterMissing:
param not found: user
# ./app/controllers/users_controller.rb:39:in `user_params'
# ./app/controllers/users_controller.rb:28:in `update'
# ./spec/requests/authentication_pages_spec.rb:63:in `block (6 levels) in <top (required)>'
2) Authentication authorization for non-signed-in users in the Users controller visiting the edit page
Failure/Error: it { should have_title('Sign in') }
expected #has_title?("Sign in") to return true, got false
# ./spec/requests/authentication_pages_spec.rb:59:in `block (6 levels) in <top (required)>'
Finished in 2.35 seconds
70 examples, 2 failures
Failed examples:
rspec ./spec/requests/authentication_pages_spec.rb:64 # Authentication authorization for non-signed-in users in the Users controller submitting to the update action
rspec ./spec/requests/authentication_pages_spec.rb:59 # Authentication authorization for non-signed-in users in the Users controller visiting the edit page
这是/spec/requests/authentication_pages_spec.rb:
describe "authorization" do
describe "for non-signed-in users" do
let(:user) { FactoryGirl.create(:user) }
describe "in the Users controller" do
describe "visiting the edit page" do
before { visit edit_user_path(user) }
it { should have_title('Sign in') }
end
describe "submitting to the update action" do
before { patch user_path(user) }
specify { expect(response).to redirect_to(signin_path) }
end
end
end
end
这是我的/app/controllers/users_controller.rb:
class UsersController < ApplicationController
before_action :signed_in_user, only: [:edit, :update]
before_action :correct_user, only: [:edit, :update]
...
def edit
end
def update
if @user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to @user
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
# Before filters
def signed_in_user
redirect_to signin_url, notice: "Please sign in." unless signed_in?
end
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user)
end
end
...并且我会在这里呈现登录页面:
/app/views/sessions/new.html.erb:
<% provide(:title, "Sign in") %>
<h1>Sign in</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(:session, url: sessions_path) do |f| %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit "Sign in", class: "btn btn-large btn-primary" %>
<% end %>
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
</div>
</div>
如果需要在此添加任何其他文件,请询问,因为我不确定是否发布了所需的所有内容。第一次失败似乎与User控制器中的强参数有关,尽管我一点一点地检查了修改过的代码,但没有发现任何差异。在第二次失败的情况下,我不知道那里会出现什么问题,因为当我在浏览器中访问它时,应用程序似乎生成了正确的标题,但测试失败了。
提前感谢您为帮助我做出的任何努力。
米甲
答案 0 :(得分:1)
您的第一个错误是ActionController::ParameterMissing
。这是因为您的user_params
方法调用了params.require(:user)
。这意味着如果没有定义params [:user],它将引发异常。
当您调用patch user_path(user)
时,您没有传入导致异常的用户参数。但是,你永远不应该user_params
,因为signed_in_user
之前应该运行并将你重定向到另一个页面。
这导致我推测您的测试用户已经登录。您可能已在sign_in
的早期部分进行了authentication_pages_spec.rb
调用。你呢?如果是这样,请将其移到context "when signed in"
块内,并且规范应该通过。
同样,如果您的测试用户实际登录了,您就不会看到登录链接 - 所以修复它也可以解决您的第二个错误。