Rails - 未知属性密码 [英] Rails - Unknown attribute password

查看:48
本文介绍了Rails - 未知属性密码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在关注 Michael Hartl 的 Ruby on Rails 教程书,以尝试将用户添加到我的应用程序中.阅读第 6 章,我添加了我认为对我的用户来说是必要的字段,特别是通过has_secure_password"进行的密码和密码确认.

I have been following Michael Hartl's Ruby on Rails tutorial book to try and add users to my application. Reading chapter 6, I have added what I believe to be the necessary fields for my user, specifically password and password confirmation via "has_secure_password".

我认为向我的用户模型添加has_secure_password"将包括属性password"和password_confirmation",前提是我向模型添加了password_digest".我已经按照书上的指示去做了.但是,当我运行测试时,Rails 给了我以下错误:

I thought that adding "has_secure_password" to my user model would include the attributes "password" and "password_confirmation" provided I add a "password_digest" to the model. I have done that as the book instructed me to. However, when I run a test, Rails gives me the following error:

Error:
UserTest#test_should_be_valid:
ActiveModel::UnknownAttributeError: unknown attribute 'password' for User.
    test/models/user_test.rb:8:in `setup'

我尝试了这个解决方案,但它仍然给了我同样的结果错误,无法识别属性password"或password_confirmation".我使用gem install bcrypt"安装了 bcrypt 并在我的 gem 文件中包含以下内容:

I tried this solution and it still gave me the same error, not recognizing the attributes "password" or "password_confirmation". I installed bcrypt using "gem install bcrypt" and included the following in my gem file:

gem 'bcrypt-ruby', :require => 'bcrypt'

gem 'bcrypt-ruby', :require => 'bcrypt'

我正在使用 Rails 5,但has_secure_password"似乎没有提供我需要的密码属性.谁能看到我错过或做错了什么导致has_secure_password"无法按预期工作?谢谢

I am using Rails 5 and it seems like "has_secure_password" is not supplying the password attributes that I need. Can anyone see what I missed or did wrong that caused "has_secure_password" to not work as intended? Thanks

用户模型:

class User < ApplicationRecord

  has_many :activities

  class User < ActiveRecord::Base

    attr_accessor :name, :email, :password, :password_confirmation
    has_secure_password

    validates :first_name, presence: true, length: {minimum: 1}
    validates :last_name, presence: true, length: {minimum: 1}
    validates :email, presence: true, uniqueness: true, length: {minimum: 5}
    validates :username, presence: true, uniqueness: true, length: {minimum: 1}
    validates :password_digest, length: {minimum: 6}
    validates :password, :confirmation => true, length: {minimum: 4}
    validates :password_confirmation, presence: true

    #-----------------------New Stuff ---------------------------------------
    acts_as_authentic do |c|
      c.crypto_provider = Authlogic::CryptoProviders::Sha512
    end
    #------------------------------------------------------------------------

    #---------------Unsure if working--------------
    #validates_presence_of :password, :on => :create
    #validates_presence_of :email
    #validates_uniqueness_of :email
    #----------------------------------------------

    def self.authenticate(email, password)
      user = find_by_email(email)
      if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
        user
      else
        nil
      end
    end

    def encrypt_password
      if password.present?
        self.password_salt = BCrypt::Engine.generate_salt
        self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
      end
    end
  end
end

为模型上的混乱代码道歉,因为我还在学习 Rails.

Apologies for the messy code on the model as I am still learning Rails.

用户控制器:

class UsersController < ApplicationController
  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      flash[:success] = 'Account created'
    else
      flash[:notice] ='ERROR: Account was not created'
      redirect_to 'users/new'
    end
  end

  def show
    @user = User.find(params[:id])
  end


  private
  def user_params
    params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation)
  end
end

用户表:

 create_table "users", force: :cascade do |t|
    t.string   "first_name"
    t.string   "last_name"
    t.string   "username"
    t.string   "email"
    t.datetime "created_at",        null: false
    t.datetime "updated_at",        null: false
    t.string   "persistence_token"
    t.string   "password_digest"
    t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
  end

用户测试:

require 'test_helper'

class UserTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
  def setup
    @user = User.new(first_name: 'test', last_name: 'tester', password: '1234',email: 'test1@mail.com',
                     password: 'foobar', password_confirmation: 'foobar')
  end
  test 'should be valid' do
    assert @user.valid?
  end
end

推荐答案

更新:

我已经测试过了,它有效.所以希望对你也有用:) 看起来 MiniTest 不能很好地与 BCrypt 一起工作.我收到了同样的错误 - 未定义密码,但后来实施了我的更改,并且进展顺利.

I have tested this out and it works. So hope will work for you as well :) Looks like MiniTest doesn't work well with BCrypt. I received the same error - undefined password, but later implemented my change and it went further well.

原答案:

从你创立的解决方案开始,我觉得这毫无意义 - 为 :password:password_confirmation 添加 getter 尤其是 setter 方法.因为 has_secure_password 创建了那些通过 BCrypt 运行的虚拟密码.那么它不是围绕加密/加密吗?如果是这样就不安全了.所以我看到只有剩下的测试选项将 BYcript 带入测试套件.我认为这样的事情可能会起作用:

As of your founded solution it made me think that this makes no sence - adding getter and especially setter methods for :password and :password_confirmation. Because has_secure_password creates those virtually that runs through BCrypt. So doesn't it goes around crypting / encrypting? If so it is not safe. So only option left for testing I see take the BYcript into the testing suite. I think something like this might do the trck:

在用户测试中:

require 'bcrypt'

  def setup
    @user = User.new(first_name: 'test', last_name: 'tester', password: BCrypt::Password.create("my password") ,email: 'test1@mail.com', password_confirmation: 'my password')
  end
  test 'should be valid' do
    assert @user.valid?
  end

请注意,我删除了重复的 password: 'foobar.由于使用该特定测试,您正在测试用户 可以 是否可以创建,因此不应传递不同的密码甚至重复的属性...为此进行另一个测试(还有结帐装置,它们非常适合创建测试对象,以及为更复杂的情况创建工厂).

Note that I removed duplicated password: 'foobar. Since with that particular test you are testing if User can be created, so shouldn't pass a different password or even duplicated attribute... Make another test for this (also checkout fixtures, they are great for creating test objects, as well as factories for more complicated cases).

当然,从您的用户模型中删除 atr_accessor :password, :password_confirmation.

And of course, remove the atr_accessor :password, :password_confirmation form your User model.

附言并请修复用户类的代码片段.还是真的像这样定义了两次?:

p.s. and please fix you code snippet for User class. Or is it really defined twice like this?:

class User < ApplicationRecord

  has_many :activities

  class User < ActiveRecord::Base

这篇关于Rails - 未知属性密码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆