无法绕过验证错误'您需要在ActiveRecord中提供至少一个属性'?

时间:2011-09-29 22:25:05

标签: ruby-on-rails

我一直在关注迈克尔哈特尔教程,但是采取了一种捷径来尝试“改进”它的例子,并创造了一个棘手的错误......

基本上,这个应用程序围绕一个用户模型和一个注册功能,使用围绕加密密码功能的大量验证;对于铁杆新手而言,这是一件非常重要的事情。

我没有严格遵循Hartl的例子,而是修改了使用脚手架来设置我的用户的方法。但是在他的项目结束时,我在尝试创建用户时开始出现此错误:

ArgumentError in UsersController#new

You need to supply at least one attribute.

这令我感到困惑,因为我试图关闭除保存之外的所有验证。 下面是一些代码片段:

my users_controller.rb #news:

class UsersController < ApplicationController
  # GET /users
  # GET /users.xml
  def index
    @users = User.all

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @users }
    end
  end

.....


  def new

    @title = "Sign up"
    @user = User.new

    #(unnecessary?)
    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @user }
    end
  end

来自我的user.rb:

class User < ActiveRecord::Base

  attr_accessor :password
  attr_accessor :username, :firstname, :lastname, :email, :password, :password_confirmation

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

  # here I am attempting to only validate when saving
  validates :allow_nil => true, :presence => true, :on => :save

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

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

  validates :username,  :presence => true,
                    :length   => { :maximum => 20 }

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

  # Automatically create the virtual attribute 'password_confirmation'.
  validates :password, :presence     => true,
                       :confirmation => true,
                       :length       => { :within => 6..40 }

  before_save :encrypt_password

   # Return true if the user's password matches the submitted password.
  def has_password?(submitted_password)
    encrypted_password == encrypt(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

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

  def initialize(attributes = {})
    @username  = attributes[:username]
    @firstname  = attributes[:firstname]
    @lastname  = attributes[:lastname]
    @email = attributes[:email]
  end

  def formatted_email
    "#{@firstname} #{@lastname}<#{@email}>"
  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

任何建议都非常感谢!

- 瑞克

PS - 每个请求。这是创建方法:

def create

    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        format.html { redirect_to(@user, :notice => 'User was successfully created.') }
        format.xml  { render :xml => @user, :status => :created, :location => @user }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
      end
    end
  end

我能够通过在模型中注释掉所有验证来获取错误消息,但我将逐个添加它们;所以我仍然需要解决这个错误......

2 个答案:

答案 0 :(得分:4)

User模型中的这一行:

validates :allow_nil => true, :presence => true, :on => :save

没有提供验证属性。您可能打算在下面列出的每个验证中包含这些选项,但不是validates的工作方式。

答案 1 :(得分:0)

我同意jimworm。验证不会在新的上运行。它只在您尝试保存或呼叫有效之前运行?你需要删除行jimworm轮廓。