Ruby on rails 3.1 RoR教程(第10.4章)-管理员属性测试失败

Ruby on rails 3.1 RoR教程(第10.4章)-管理员属性测试失败,ruby-on-rails-3.1,rspec,railstutorial.org,Ruby On Rails 3.1,Rspec,Railstutorial.org,我是一名RoR学习者,我参加了Michael Hartl的RoR教程,但实际上我在第10.4章遇到了一个问题。我做了10.42之前的所有清单,但是我的Rspec测试有3个失败 它说: 1) “用户管理员”属性应响应“管理员” 失败/错误:@user=user.create!(@attr) ActiveRecord::RecordInvalid:验证失败:名称不能为空, 电子邮件不能为空,电子邮件无效,密码不能为空, 密码太短(最少6个字符) ./spec/requests/users_spec.

我是一名RoR学习者,我参加了Michael Hartl的RoR教程,但实际上我在第10.4章遇到了一个问题。我做了10.42之前的所有清单,但是我的Rspec测试有3个失败

它说:

1) “用户管理员”属性应响应“管理员” 失败/错误:@user=user.create!(@attr) ActiveRecord::RecordInvalid:验证失败:名称不能为空, 电子邮件不能为空,电子邮件无效,密码不能为空, 密码太短(最少6个字符) ./spec/requests/users_spec.rb:52:in`block(3层)in`

2) 默认情况下,用户管理员属性不应为管理员 失败/错误:@user=user.create!(@attr) ActiveRecord::RecordInvalid:验证失败:名称不能为空, 电子邮件不能为空,电子邮件无效,密码不能为空, 密码太短(最少6个字符) ./spec/requests/users_spec.rb:52:in`block(3层)in`

3) “用户管理员”属性应可转换为管理员 失败/错误:@user=user.create!(@attr) ActiveRecord::RecordInvalid:验证失败:名称不能为空, 电子邮件不能为空,电子邮件无效,密码不能为空, 密码太短(最少6个字符) ./spec/requests/users_spec.rb:52:in`block(3层)in`

我已经仔细查看了我的用户\u controllers\u spec.rb和我的用户\u spec.rb,但是我找不到错误的解释。有人有主意吗

require 'spec_helper'

describe UsersController do
  render_views

  describe "GET 'index'" do

    describe "for non-signed-in users" do
      it "should deny access" do
        get :index
        response.should redirect_to(signin_path)
        flash[:notice].should =~ /sign in/i
      end
    end

    describe "for signed-in users" do

      before(:each) do
        @user = test_sign_in(Factory(:user))
        second = Factory(:user, :name => "Bob", :email => "another@example.com")
        third  = Factory(:user, :name => "Ben", :email => "another@example.net")
        #@users = [@user, second, third]
        @users = [@user, second, third]
        30.times do
          @users << Factory(:user, :name => Factory.next(:name),
                                   :email => Factory.next(:email))
        end
      end


      it "should be successful" do
        get :index
        response.should be_success
      end

      it "should have the right title" do
        get :index
        response.should have_selector("title", :content => "All users")
      end

    it "should have an element for each user" do
        get :index
        @users[0..2].each do |user|
          response.should have_selector("li", :content => user.name)
        end
      end

      it "should paginate users" do
        get :index
        response.should have_selector("div.pagination")
        response.should have_selector("span.disabled", :content => "Previous")
        response.should have_selector("a", :href => "/users?escape=false&page=2",
                                           :content => "2")
        response.should have_selector("a", :href => "/users?escape=false&page=2",
                                           :content => "Next")
      end
    end
  end



   describe "GET 'show'" do

        before(:each) do
          @user = Factory(:user)
        end

        it "should be successful" do
          get :show, :id => @user
          response.should be_success
        end

        it "should find the right user" do
          get :show, :id => @user
          assigns(:user).should == @user
        end

     it "should have the right title" do
          get :show, :id => @user
          response.should have_selector("title", :content => @user.name)
        end

        it "should include the user's name" do
          get :show, :id => @user
          response.should have_selector("h1", :content => @user.name)
        end

        it "should have a profile image" do
          get :show, :id => @user
          response.should have_selector("h1>img", :class => "gravatar")
        end
      end

      describe "GET 'new'" do
        it "should be successful" do
          get 'new'
          response.should be_success
        end

        it "should have the right title" do
          get 'new'
          response.should have_selector("title", :content => "Sign up")
        end
      end
      describe "POST 'create'" do

        describe "failure" do

          before(:each) do
            @attr = { :name => "", :email => "", :password => "",
                      :password_confirmation => "" }
          end

          it "should not create a user" do
            lambda do
              post :create, :user => @attr
            end.should_not change(User, :count)
          end

          it "should have the right title" do
            post :create, :user => @attr
            response.should have_selector("title", :content => "Sign up")
          end

          it "should render the 'new' page" do
            post :create, :user => @attr
            response.should render_template('new')
          end
         end


        describe "success" do

          before(:each) do
            @attr = { :name => "New User", :email => "user@example.com",
                      :password => "foobar", :password_confirmation => "foobar" }
          end

          it "should create a user" do
            lambda do
              post :create, :user => @attr
            end.should change(User, :count).by(1)
          end

          it "should redirect to the user show page" do
            post :create, :user => @attr
            response.should redirect_to(user_path(assigns(:user)))
          end    

          it "should have a welcome message" do
            post :create, :user => @attr
            flash[:success].should =~ /welcome to the sample app/i
          end

          it "should sign the user in" do
            post :create, :user => @attr
            controller.should be_signed_in
          end


        end
      end
    describe "GET 'edit'" do

        before(:each) do
          @user = Factory(:user)
          test_sign_in(@user)
        end

        it "should be successful" do
          get :edit, :id => @user
          response.should be_success
        end

        it "should have the right title" do
          get :edit, :id => @user
          response.should have_selector("title", :content => "Edit user")
        end

        it "should have a link to change the Gravatar" do
          get :edit, :id => @user
          gravatar_url = "http://gravatar.com/emails"
          response.should have_selector("a", :href => gravatar_url,
                                             :content => "change")
        end
      end
     describe "PUT 'update'" do

        before(:each) do
          @user = Factory(:user)
          test_sign_in(@user)
        end

        describe "failure" do

          before(:each) do
            @attr = { :email => "", :name => "", :password => "",
                      :password_confirmation => "" }
          end

          it "should render the 'edit' page" do
            put :update, :id => @user, :user => @attr
            response.should render_template('edit')
          end

          it "should have the right title" do
            put :update, :id => @user, :user => @attr
            response.should have_selector("title", :content => "Edit user")
          end
        end

        describe "success" do

          before(:each) do
            @attr = { :name => "New Name", :email => "user@example.org",
                      :password => "barbaz", :password_confirmation => "barbaz" }
          end

          it "should change the user's attributes" do
            put :update, :id => @user, :user => @attr
            @user.reload
            @user.name.should  == @attr[:name]
            @user.email.should == @attr[:email]
          end

          it "should redirect to the user show page" do
            put :update, :id => @user, :user => @attr
            response.should redirect_to(user_path(@user))
          end

          it "should have a flash message" do
            put :update, :id => @user, :user => @attr
            flash[:success].should =~ /updated/
          end
        end
      end
    describe "authentication of edit/update pages" do

        before(:each) do
          @user = Factory(:user)
        end

        describe "for non-signed-in users" do

          it "should deny access to 'edit'" do
            get :edit, :id => @user
            response.should redirect_to(signin_path)
          end

          it "should deny access to 'update'" do
            put :update, :id => @user, :user => {}
            response.should redirect_to(signin_path)
          end
        end

      describe "for signed-in users" do

          before(:each) do
            wrong_user = Factory(:user, :email => "user@example.net")
            test_sign_in(wrong_user)
          end

          it "should require matching users for 'edit'" do
            get :edit, :id => @user
            response.should redirect_to(root_path)
          end

          it "should require matching users for 'update'" do
            put :update, :id => @user, :user => {}
            response.should redirect_to(root_path)
          end
        end
      end

    describe "DELETE 'destroy'" do

        before(:each) do
          @user = Factory(:user)
        end

        describe "as a non-signed-in user" do
          it "should deny access" do
            delete :destroy, :id => @user
            response.should redirect_to(signin_path)
          end
        end

        describe "as a non-admin user" do
          it "should protect the page" do
            test_sign_in(@user)
            delete :destroy, :id => @user
            response.should redirect_to(root_path)
          end
        end

        describe "as an admin user" do

          before(:each) do
            admin = Factory(:user, :email => "admin@example.com", :admin => true)
            test_sign_in(admin)
          end

          it "should destroy the user" do
            lambda do
              delete :destroy, :id => @user
            end.should change(User, :count).by(-1)
          end

          it "should redirect to the users page" do
            delete :destroy, :id => @user
            response.should redirect_to(users_path)
          end
        end
      end
    end
编辑:User.rb

 == Schema Information

 Table name: users

  id         :integer         not null, primary key
  name       :string(255)
  email      :string(255)
  created_at :datetime
  updated_at :datetime
//it's outcommented

class User < ActiveRecord::Base
 attr_accessor :password
  attr_accessible :name, :email, :password, :password_confirmation

 email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i


validates :name, :presence => true,
:length   => { :maximum => 50 }

 validates :email, :presence => true,
 :format   => { :with => email_regex },
 :uniqueness => { :case_sensitive => false }

 validates :password, :presence     => true,
                       :confirmation => true,
                       :length       => { :within => 6..40 }

  before_save :encrypt_password

   def has_password?(submitted_password)
    encrypted_password == encrypt(submitted_password)
  end

  def self.authenticate_with_salt(id, cookie_salt)
    user = find_by_id(id)
    (user && user.salt == cookie_salt) ? user : nil
  end

  def self.authenticate(email, submitted_password)
    user = find_by_email(email)
    return nil  if user.nil?
    return user if user.has_password?(submitted_password)
  end

   def self.authenticate(email, submitted_password)
    user = find_by_email(email)
    return nil  if user.nil?
    return user if user.has_password?(submitted_password)
  end

  private

    def encrypt_password
      self.salt = make_salt unless has_password?(password)
      self.encrypted_password = encrypt(password)
    end

    def encrypt(string)
      secure_hash("#{salt}--#{string}")
    end

    def make_salt
      secure_hash("#{Time.now.utc}--#{password}")
    end

    def secure_hash(string)
      Digest::SHA2.hexdigest(string)
    end



end
==架构信息
表名:用户
id:整数不为空,主键
名称:字符串(255)
电子邮件:string(255)
创建时间:datetime
更新时间:datetime
//这篇文章被评论得不值一提
类用户true,
:length=>{:max=>50}
验证:email,:presence=>true,
:format=>{:with=>email_regex},
:唯一性=>{:区分大小写=>false}
验证:password,:presence=>true,
:confirmation=>true,
:length=>{:within=>6..40}
保存前:加密密码
def有密码?(已提交密码)
加密密码==加密(已提交密码)
结束
def自我验证使用_盐(id,cookie_盐)
用户=通过\u id(id)查找\u
(user&&user.salt==cookie\u salt)?用户:无
结束
def自我验证(电子邮件、提交的密码)
用户=通过电子邮件查找(电子邮件)
如果user.nil,则返回nil?
如果用户有密码,则返回用户?(已提交密码)
结束
def自我验证(电子邮件、提交的密码)
用户=通过电子邮件查找(电子邮件)
如果user.nil,则返回nil?
如果用户有密码,则返回用户?(已提交密码)
结束
私有的
def加密密码
self.salt=make_salt,除非有密码?(密码)
self.encrypted_password=加密(密码)
结束
def加密(字符串)
安全散列(“#{salt}--#{string}”)
结束
def制盐
安全散列(“#{Time.now.utc}--#{password}”)
结束
def secure_散列(字符串)
摘要::SHA2.hexdigest(字符串)
结束
结束
如果缺少一些重要的细节,请询问,我准备更新这篇文章(只是不想让它过载,因为代码已经足够大了)


谢谢你的关注

您的用户_spec.rb与教程中清单10.34中的用户不匹配。 更具体地说,
before(:each)

您的用户_spec.rb:

before(:each) do
    @user = User.create!({
    :name => "Example User",
    :email => "user@example.com",
    :password => "foobar",
    :password_confirmation => "foobar"
    })#(@attr)
end
清单10.34:

before(:each) do
    @user = User.create!(@attr)
end

我最近遇到了同样的问题,并通过从create方法调用中删除bang(
)来解决它:

@user = User.create(@attr)

我以前有过(#(@attr)),但它不起作用。所以我试着自己填写,看看错误是否会改变。但它们完全相同,并且与(@attr)相同。(只是想展示一下,我已经尝试过的)。我确实怀疑(:这很奇怪,因为在前面的示例中它似乎起作用,我不能确定
@attr
正在发生任何变化。也许你可以尝试删除
{
}
关于属性,但不确定这是否有区别。这就是问题所在,我也不明白:/为什么(@attr)突然不起作用了?我只是想把{和}去掉,但你是对的,没有区别。哇!这让我发疯了。如果你仍然卡住了,你能粘贴用户模型吗?(可能不是用户控制器规范)
@user = User.create(@attr)