我在Ruby中有这个模型,但它抛出ActiveModel::ForbiddenAttributesError

class User < ActiveRecord::Base
  attr_accessor :password
  validates :username, :presence => true, :uniqueness => true, :length => {:in => 3..20}
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, :uniqueness => true, format: { with: VALID_EMAIL_REGEX }

  validates :password, :confirmation => true
  validates_length_of :password, :in => 6..20, :on => :create

  before_save :encrypt_password
  after_save :clear_password

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

  def clear_password
    self.password = nil
  end
end

当我运行这个动作时

  def create
    @user = User.new(params[:user])
    if @user.save
      flash[:notice] = "You Signed up successfully"
      flash[:color]= "valid"
    else
      flash[:notice] = "Form is invalid"
      flash[:color]= "invalid"
    end
    render "new"
  end

在ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]上。

你能告诉我如何消除这个错误或者建立一个正确的用户登记表吗?


当前回答

或者你也可以使用Protected Attributes宝石,但是这违背了要求强参数的目的。然而,如果你正在升级一个旧的应用程序,Protected Attributes确实提供了一个简单的升级途径,直到你可以将attr_accessible重构为强参数。

其他回答

我猜你用的是Rails 4。如果是这样,必需的参数必须标记为必需的。

你可能想这样做:

class UsersController < ApplicationController

  def create
    @user = User.new(user_params)
    # ...
  end

  private

  def user_params
    params.require(:user).permit(:username, :email, :password, :salt, :encrypted_password)
  end
end

另一个原因是您通过一个方法重写了permitted_params。例如

def permitted_params
   params.permit(:email, :password)
end

或者你也可以使用Protected Attributes宝石,但是这违背了要求强参数的目的。然而,如果你正在升级一个旧的应用程序,Protected Attributes确实提供了一个简单的升级途径,直到你可以将attr_accessible重构为强参数。

对于使用CanCan的人。如果使用CanCan和Rails 4+,人们可能会遇到这种情况。在CanCan更新之前,请尝试AntonTrapps相当干净的解决方案:

在ApplicationController中:

before_filter do
  resource = controller_name.singularize.to_sym
  method = "#{resource}_params"
  params[resource] &&= send(method) if respond_to?(method, true)
end

在资源控制器中(例如NoteController):

private
def note_params
  params.require(:note).permit(:what, :ever)
end

更新:

下面是CanCan的一个后续项目,叫做canancan,看起来很有前途:

灿灿

如果你在Rails 4上,你得到这个错误,如果你在模型上使用枚举,如果你定义了这样的符号,它可能会发生:

class User
  enum preferred_phone: [:home_phone, :mobile_phone, :work_phone]
end

表单将传递一个无线选择器作为字符串参数。我的情况就是这样。简单的解决方法是将enum更改为字符串而不是符号

enum preferred_phone: %w[home_phone mobile_phone work_phone]
# or more verbose
enum preferred_phone: ['home_phone', 'mobile_phone', 'work_phone']