Rails,未定义的方法错误。但我可以在rails控制台中使用此方法

时间:2012-02-13 07:12:42

标签: ruby-on-rails

在我的rspec测试中。我得到NoM​​ethodError:            未定义的方法`password_digest ='。

但是在rails控制台中。我可以使用.password_digest方法。

我很困惑。我搜索谷歌。有关于此的严重线程。甚至在stackoverflow中。但那些没有帮助。我确实将password_digest作为我数据库中的一个字段。

我甚至可以设置我的password_digest

请参阅:

1.9.2-p290 :005 > user.password_digest
 => "$2a$10$X8CSsstOqZKKA6qVHpW9.uH5Lzd7dxfGNCAxvIbePpcfBg8KFbD4y" 
1.9.2-p290 :006 > user.password_digest = 1
 => 1 
1.9.2-p290 :007 > user.password_digest
 => 1 

而且,在我的应用程序中。一切似乎都很好。那真是怪了。 请帮忙......

1.9.2-p290 :002 > User.first.password_digest
  User Load (0.3ms)  SELECT "users".* FROM "users" LIMIT 1
 => "$2a$10$NCfX2SgKeqGARJ68StxRJuCbbbK7g18n5FPxbHY5THwg4pAdHUvui" 
1.9.2-p290 :003 > 
[5]+  Stopped                 rails console
luke@Macbook-Pro~/Documents/workspace/RoR/rails_projects/sample_app2012$ bundle exec rspec spec/models/user_spec.rb

DEPRECATION WARNING: The InstanceMethods module inside ActiveSupport::Concern will be no longer included automatically. Please define instance methods directly in #<Class:0x000001029f6688> instead. (called from <top (required)> at /Users/luke/Documents/workspace/RoR/rails_projects/sample_app2012/spec/models/user_spec.rb:14)
DEPRECATION WARNING: The InstanceMethods module inside ActiveSupport::Concern will be no longer included automatically. Please define instance methods directly in #<Class:0x000001029f6688> instead. (called from <top (required)> at /Users/luke/Documents/workspace/RoR/rails_projects/sample_app2012/spec/models/user_spec.rb:14)
FFFFFFFFFFFFFFFFFFFFF

Failures:

  1) User 
     Failure/Error: @user = User.new(name: "Example User", email: "user@example.com",
     NoMethodError:
       undefined method `password_digest=' for #<User:0x00000100beee60>
     # ./spec/models/user_spec.rb:17:in `new'
     # ./spec/models/user_spec.rb:17:in `block (2 levels) in <top (required)>'
..... There are 19 more failures, to save space, i didn't paste them here.

这是我的user_spec.rb代码:

# == Schema Information
#
# Table name: users
#
#  id         :integer         not null, primary key
#  name       :string(255)
#  email      :string(255)
#  created_at :datetime        not null
#  updated_at :datetime        not null
#

require 'spec_helper'

describe User do

  before(:each) do
    @user = User.new(name: "Example User", email: "user@example.com", 
                     password: "foobar", password_confirmation: "foobar")
  end



  subject { @user }

  it { should respond_to(:name) }
  it { should respond_to(:email) }
  it { should respond_to(:password_digest)}
  it { should respond_to(:password)}
  it { should respond_to(:password_confirmation)}
  it { should respond_to(:remember_token) }
  it { should respond_to(:authenticate) }

  it { should be_valid }

  describe "when name is not present" do
    before { @user.name = " " }
    it { should_not be_valid }
  end

  describe "when email is not present" do
    before { @user.email = " " }
    it { should_not be_valid }
  end

  describe "when name is too long" do
    before { @user.name = "a" * 51 }
    it { should_not be_valid }
  end

  describe "when email format is valid" do
    valid_addresses = %w[user@foo.com THE_USER@foo.bar.org first.last@foo.jp]
    valid_addresses.each do |valid_address|
        before { @user.email = valid_address}
        it {should be_valid }
    end
  end

  describe "when email address is already taken" do
    before do
        user_with_same_email = @user.dup
        user_with_same_email.email = @user.email.upcase
        user_with_same_email.save
    end

    it { should_not be_valid }
  end

  describe "when password is not present" do
    before { @user.password = @user.password_confirmation = " " }
    it {should_not be_valid}
  end

  describe "when password doesn't match confirmation" do
    before { @user.password_confirmation = "mismatch" }
    it { should_not be_valid }
  end

  describe "return value of authenticate method" do
    before { @user.save }
    let(:found_user) { User.find_by_email(@user.email) }

    describe "with valid password" do
        it { should == found_user.authenticate(@user.password) }
    end

    describe "with invalid password" do
        let(:user_for_invalid_password) { found_user.authenticate("invalid") }

        it { should_not == user_for_invalid_password }
        specify { user_for_invalid_password.should be_false }
    end

    describe "remember token" do
      before { @user.save }
      its(:remember_token) { should_not be_blank }
    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        not null
#  updated_at :datetime        not null



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



  validates :name, presence: true, :length => { maximum: 50 }
  valid_email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, :presence   => true,
                    :format     => { with: valid_email_regex },
                    :uniqueness => { case_sensitive: false }


  validates :password,  length: { minimum: 6}
end

6 个答案:

答案 0 :(得分:6)

也只是坚持了一段时间。

别忘了

新迁移后

rake db:test:prepare

答案 1 :(得分:1)

class User有方法password_diges但没有方法password_digest = 这不是相同的方法,因此User的实例不对password_digest负责 它应该返回password_digest但是应该没有response_to password_digest我认为

答案 2 :(得分:0)

您可以在控制台中使用User.first.password_digest,因为password_digestpassword_digest=的方法不同。

password_digest=与:

相同
    def password_digest=(digest)
      @password_digest = digest
    end

否则password_digest

    def password_digest
      @password_digest
    end 

答案 3 :(得分:0)

在您的控制台中,您正在尝试password_digest方法,而不是password_digest=方法。您是否能够在控制台中执行以下操作? User.first.password_digest = "$2a$10$NCfX2SgKeqGARJ68StxRJuCbbbK7g18n5FPxbHY5THwg4pAdHUvui"

我认为您的问题可能源于您将User模型中的某些属性仅指定为attr_accessible。尝试将:password_digest添加到该列表中,看看您的测试是否通过。

答案 4 :(得分:0)

您好我是RoR的新手,我学习了RailsTutorial并遇到了这个问题。经过长时间的搜索,我发现我的db / test.sqlite3还没有更新。这意味着有&#39; password_digest&#39;在我的db / development.sqlite3中,但我的db / test.sqlite3中没有该列。
在我运行命令&ra; db:reset&#39;之后并且&#39; rake db:test:prepare&#39;,问题已经消失。

答案 5 :(得分:0)

我昨天遇到了完全相同的问题。开发和测试环境中的控制台运行良好。 Web应用程序本身也很好用。但是测试(与所描述的问题几乎相同的测试)因no method错误而失败。

我试图停止弹簧,重新创建测试数据库,杀死memcached。但它不起作用。

最后,我在夹具文件test/fixtures/users.yml中添加了一些数据。

harry:
  name: Harry
  email: harry@example.com
  password_digest: <%= User.digest('password') %>

以前是空的。然后测试通过了。之后我让user.yml空了。测试仍然通过。

我不知道为什么。但希望它有所帮助。