[英]Hartl Ruby on Rails Tutorial 9.2.2 Validation failed: Name has already been taken
Have been following the RoR tutorial and am rather stuck on section 9.2.2. 一直在遵循RoR教程,而是停留在9.2.2节。 The GET Request and Patch request tests are failing with the following error messages and I can't see why:
GET请求和修补程序请求测试失败,并显示以下错误消息,我看不出原因:
1) Authentication authorization as wrong user submitting a GET request to the Users#edit action
Failure/Error: let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") }
ActiveRecord::RecordInvalid:
Validation failed: Name has already been taken
# ./spec/requests/authentication_pages_spec.rb:62:in `block (4 levels) in <top (required)>'
# ./spec/requests/authentication_pages_spec.rb:66:in `block (5 levels) in <top (required)>'
2) Authentication authorization as wrong user submitting a GET request to the Users#edit action
Failure/Error: let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") }
ActiveRecord::RecordInvalid:
Validation failed: Name has already been taken
# ./spec/requests/authentication_pages_spec.rb:62:in `block (4 levels) in <top (required)>'
# ./spec/requests/authentication_pages_spec.rb:66:in `block (5 levels) in <top (required)>'
3) Authentication authorization as wrong user submitting a PATCH request to the Users#update action
Failure/Error: let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") }
ActiveRecord::RecordInvalid:
Validation failed: Name has already been taken
# ./spec/requests/authentication_pages_spec.rb:62:in `block (4 levels) in <top (required)>'
# ./spec/requests/authentication_pages_spec.rb:72:in `block (5 levels) in <top (required)>'
Failed examples:
rspec ./spec/requests/authentication_pages_spec.rb:67 # Authentication authorization as wrong user submitting a GET request to the Users#edit action
rspec ./spec/requests/authentication_pages_spec.rb:68 # Authentication authorization as wrong user submitting a GET request to the Users#edit action
rspec ./spec/requests/authentication_pages_spec.rb:73 # Authentication authorization as wrong user submitting a PATCH request to the Users#update action
I have tried: 我努力了:
rake db:reset rake test:prepare
but makes no difference 但没有区别
following is my authentication_pages_spec.rb 以下是我的authentication_pages_spec.rb
require 'spec_helper'
describe "Authentication" do
subject { page }
describe "signin page" do
before { visit signin_path }
it { should have_content('Sign in') }
it { should have_title('Sign in') }
end
describe "signin" do
before { visit signin_path }
describe "with invalid information" do
before { click_button "Sign in" }
it { should have_title('Sign in') }
it { should have_selector('div.alert.alert-error') }
describe "after visiting another page" do
before { click_link "Home" }
it { should_not have_selector('div.alert.alert-error') }
end
end
describe "with valid information" do
let(:user) { FactoryGirl.create(:user) }
before {sign_in user}
it { should have_title(user.name) }
it { should have_link('Profile', href: user_path(user)) }
it { should have_link('Settings', href: edit_user_path(user)) }
it { should have_link('Sign out', href: signout_path) }
it { should_not have_link('Sign in', href: signin_path) }
end
end
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
describe "as wrong user" do
let(:user) { FactoryGirl.create(:user) }
let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") }
before { sign_in user, no_capybara: true }
describe "submitting a GET request to the Users#edit action" do
before { get edit_user_path(wrong_user) }
specify { expect(response.body).not_to match(full_title('Edit user')) }
specify { expect(response).to redirect_to(root_url) }
end
describe "submitting a PATCH request to the Users#update action" do
before { patch user_path(wrong_user) }
specify { expect(response).to redirect_to(root_url) }
end
end
end
end
users_controller.rb users_controller.rb
class UsersController < ApplicationController
before_action :signed_in_user, only: [:edit, :update]
before_action :correct_user, only: [:edit, :update]
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
sign_in @user
flash[:success] = "Welcome to the Sample App!"
redirect_to @user
else
render 'new'
end
end
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
sessions_helper.rb sessions_helper.rb
module SessionsHelper
def sign_in(user)
remember_token = User.new_remember_token
cookies.permanent[:remember_token] = remember_token
user.update_attribute(:remember_token, User.digest(remember_token))
self.current_user = user
end
def signed_in?
!current_user.nil?
end
def current_user=(user)
@current_user = user
end
def current_user
remember_token = User.digest(cookies[:remember_token])
@current_user ||= User.find_by(remember_token: remember_token)
end
def current_user?(user)
user == current_user
end
def sign_out
current_user.update_attribute(:remember_token, User.digest(User.new_remember_token))
cookies.delete(:remember_token)
self.current_user = nil
end
end
spec/support/utilities.rb 规格/支持/ utilities.rb
def full_title(page_title)
base_title = "Ruby on Rails Tutorial Sample App"
if page_title.empty?
base_title
else
"#{base_title} | #{page_title}"
end
end
def sign_in(user, options={})
if options[:no_capybara]
# Sign in when not using Capybara.
remember_token = User.new_remember_token
cookies[:remember_token] = remember_token
user.update_attribute(:remember_token, User.digest(remember_token))
else
visit signin_path
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
end
end
spec/factories.rb 投机/ factories.rb
FactoryGirl.define do
factory :user do
name "Michael Hartl"
email "michael@example.com"
password "foobar"
password_confirmation "foobar"
end
end
Any assistance would be greatly appreciated. 任何帮助将不胜感激。
The problem is that both user
and wrong_user
have the same name. 问题是
user
和wrong_user
user
都具有相同的名称。 You can solve this in the spec by passing a unique name: 您可以在规范中通过传递唯一名称来解决此问题:
let(:wrong_user) do
FactoryGirl.create(:user, name: 'The Wrong Dude', email: "wrong@example.com")
end
Or by changing your factory to use a sequence : 或通过更改工厂以使用序列 :
FactoryGirl.define do
factory :user do
sequence(:name) {|n| "J. Random User #{n}" }
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.