Michael Hartl의 Ruby on Rails 튜토리얼에서 장기 휴가 (1 년) 후 연결이 끊어졌습니다. 통합 테스트에서 user_param 오류가 발생했습니다. 필자는 문서를 비롯한 강력한 매개 변수에 대해 잘못 이해할 수있는 원인을 파악하기 위해 4 곳의 출처를 살펴 보았습니다.Ruby on rails 튜토리얼 - 통합 테스트 - 유효/유효하지 않은 사용자 정보 로그인 실패 - user_param 문제?
지난 주에 다시 시작한 이래로 일반적으로 튜토리얼 프로젝트를 알게되어 4 시간이 걸렸으며 7-12 시간에 걸쳐 12 시간을 읽은 다음이 문제를 쫓아 왔습니다. 나는 내가이 물건들에 너무 빨리 스캔해야하는 것처럼 느껴지고있다. & 나는 추적 오류가 좋지 않다는 것을 날카롭게 알고있다.
내가 누락 된 부분에 대해 알려 주실 수 있습니까? 이 유형의 문제를 촬영하는 데 문제가 있으면 알려주고 싶습니다. 시간 내 줘서 고마워! user_signup_test 여기
class UsersController < ApplicationController
before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: :destroy
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted"
redirect_to users_url
end
def index
@users = User.paginate(page: params[:page])
end
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
@user.send_activation_email
flash[:info] = "Please check your email to activate your account."
redirect_to root_url
else
render 'new'
end
end
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
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
# Confirms a logged-in user.
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
# Confirms the correct user.
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user)
end
# Confirms an admin user.
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end
것 : 여기
require 'test_helper'
class UsersSignupTest < ActionDispatch::IntegrationTest
def setup
ActionMailer::Base.deliveries.clear
end
test "invalid signup information" do
get signup_path
assert_no_difference 'User.count' do
post users_path, params: { user: { name: "",
email: "[email protected]",
password: "foo",
password_confirmation: "bar" } }
end
assert_template 'users/new'
assert_select 'div#error_explanation'
assert_select 'div.field_with_errors'
end
test "valid signup information with account activation" do
get signup_path
assert_difference 'User.count', 1 do
post users_path, params: { user: { name: "Example User",
email: "[email protected]",
password: "password",
password_confirmation: "password" } }
end
assert_equal 1, ActionMailer::Base.deliveries.size
user = assigns(:user)
assert_not user.activated?
# Try to log in before activation.
log_in_as(user)
assert_not is_logged_in?
# Invalid activation token
get edit_account_activation_path("invalid token", email: user.email)
assert_not is_logged_in?
# Valid token, wrong email
get edit_account_activation_path(user.activation_token, email: 'wrong')
assert_not is_logged_in?
# Valid activation token
get edit_account_activation_path(user.activation_token, email: user.email)
assert user.reload.activated?
follow_redirect!
assert_template 'users/show'
assert is_logged_in?
end
end
문제의 컨트롤러 (users_controller) 여기
ERROR["test_password_resets", PasswordResetsTest, 2016-10-20 15:24:37 +0000]
test_password_resets#PasswordResetsTest (1476977077.03s)
NoMethodError: NoMethodError: undefined method `[]' for nil:NilClass
app/controllers/password_resets_controller.rb:10:in `create'
test/integration/password_resets_test.rb:14:in `block in <class:PasswordResetsTest>'
app/controllers/password_resets_controller.rb:10:in `create'
test/integration/password_resets_test.rb:14:in `block in <class:PasswordResetsTest>'
ERROR["test_invalid_signup_information", UsersSignupTest, 2016-10-20 15:24:37 +0000]
test_invalid_signup_information#UsersSignupTest (1476977077.04s)
ActionController::ParameterMissing: ActionController::ParameterMissing: param is missing or the value is empty: user
app/controllers/users_controller.rb:52:in `user_params'
app/controllers/users_controller.rb:25:in `create'
test/integration/user_signup_test.rb:12:in `block (2 levels) in <class:UsersSignupTest>'
test/integration/user_signup_test.rb:11:in `block in <class:UsersSignupTest>'
app/controllers/users_controller.rb:52:in `user_params'
app/controllers/users_controller.rb:25:in `create'
test/integration/user_signup_test.rb:12:in `block (2 levels) in <class:UsersSignupTest>'
test/integration/user_signup_test.rb:11:in `block in <class:UsersSignupTest>'
ERROR["test_valid_signup_information_with_account_activation", UsersSignupTest, 2016-10-20 15:24:37 +0000]
test_valid_signup_information_with_account_activation#UsersSignupTest (1476977077.05s)
ActionController::ParameterMissing: ActionController::ParameterMissing: param is missing or the value is empty: user
app/controllers/users_controller.rb:52:in `user_params'
app/controllers/users_controller.rb:25:in `create'
test/integration/user_signup_test.rb:25:in `block (2 levels) in <class:UsersSignupTest>'
test/integration/user_signup_test.rb:24:in `block in <class:UsersSignupTest>'
app/controllers/users_controller.rb:52:in `user_params'
app/controllers/users_controller.rb:25:in `create'
test/integration/user_signup_test.rb:25:in `block (2 levels) in <class:UsersSignupTest>'
test/integration/user_signup_test.rb:24:in `block in <class:UsersSignupTest>'
FAIL["test_should_get_edit", PasswordResetsControllerTest, 2016-10-20 15:24:37 +0000]
test_should_get_edit#PasswordResetsControllerTest (1476977077.05s)
Expected response to be a <success>, but was <302>
test/controllers/password_resets_controller_test.rb:11:in `block in <class:PasswordResetsControllerTest>'
것 : 여기
내가 콘솔에서지고있어 오류 메시지입니다 마지막 컨트롤러입니다 - 그 중 하나를 놓친 ...require 'test_helper'
class PasswordResetsTest < ActionDispatch::IntegrationTest
def setup
ActionMailer::Base.deliveries.clear
@user = users(:michael)
end
test "password resets" do
get new_password_reset_path
assert_template 'password_resets/new'
# Invalid email
post password_resets_path, password_reset: { email: "" }
assert_not flash.empty?
assert_template 'password_resets/new'
# Valid email
post password_resets_path,
password_reset: { email: @user.email }
assert_not_equal @user.reset_digest, @user.reload.reset_digest
assert_equal 1, ActionMailer::Base.deliveries.size
assert_not flash.empty?
assert_redirected_to root_url
# Password reset form
user = assigns(:user)
# Wrong email
get edit_password_reset_path(user.reset_token, email: "")
assert_redirected_to root_url
# Inactive user
user.toggle!(:activated)
get edit_password_reset_path(user.reset_token, email: user.email)
assert_redirected_to root_url
user.toggle!(:activated)
# Right email, wrong token
get edit_password_reset_path('wrong token', email: user.email)
assert_redirected_to root_url
# Right email, right token
get edit_password_reset_path(user.reset_token, email: user.email)
assert_template 'password_resets/edit'
assert_select "input[name=email][type=hidden][value=?]", user.email
# Invalid password & confirmation
patch password_reset_path(user.reset_token),
email: user.email,
user: { password: "foobaz",
password_confirmation: "barquux" }
assert_select 'div#error_explanation'
# Empty password
patch password_reset_path(user.reset_token),
email: user.email,
user: { password: "",
password_confirmation: "" }
assert_select 'div#error_explanation'
# Valid password & confirmation
patch password_reset_path(user.reset_token),
email: user.email,
user: { password: "foobaz",
password_confirmation: "foobaz" }
assert is_logged_in?
assert_not flash.empty?
assert_redirected_to user
end
end
PasswordResetController : 나는 당신이 user
매개 변수 전에 params
키를 제거해야한다고 생각
class PasswordResetsController < ApplicationController
before_action :get_user, only: [:edit, :update]
before_action :valid_user, only: [:edit, :update]
before_action :check_expiration, only: [:edit, :update] # Case (1)
def new
end
def create
@user = User.find_by(email: params[:password_reset][:email].downcase)
if @user
@user.create_reset_digest
@user.send_password_reset_email
flash[:info] = "Email sent with password reset instructions"
redirect_to root_url
else
flash.now[:danger] = "Email address not found"
render 'new'
end
end
def edit
end
def update
if params[:user][:password].empty? # Case (3)
@user.errors.add(:password, "can't be empty")
render 'edit'
elsif @user.update_attributes(user_params) # Case (4)
log_in @user
flash[:success] = "Password has been reset."
redirect_to @user
else
render 'edit' # Case (2)
end
end
private
def user_params
params.require(:user).permit(:password, :password_confirmation)
end
# Before filters
def get_user
@user = User.find_by(email: params[:email])
end
# Confirms a valid user.
def valid_user
unless (@user && @user.activated? &&
@user.authenticated?(:reset, params[:id]))
redirect_to root_url
end
end
# Checks expiration of reset token.
def check_expiration
if @user.password_reset_expired?
flash[:danger] = "Password reset has expired."
redirect_to new_password_reset_url
end
end
end
감사합니다. 양쪽 모두를 위해 그렇게 했어. .. 다른 하나를 찌르는 곳이 확실하지 않다. 그러나 굉장한 & 빠른 응답! 여전히 "test_password_resets", PasswordResetsTest 및 "test_should_get_edit", PasswordResetsControllerTest – Mirv
PS : 11 월 20 일자로 Michael Hartl 's 가이드를 사용하는 다른 사용자의 경우 params &에 대한 마지막 개정 이후 허용 된 구문이 변경되었습니다. rake/rails 명령이 콘솔에 자주 나열되지 않습니다. – Mirv