我在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]上。
你能告诉我如何消除这个错误或者建立一个正确的用户登记表吗?
对于使用canancan的用户:
如果canancan不能找到正确的params方法,就会得到这个错误。
对于:create操作,CanCan将尝试初始化一个带有净化过的输入的新实例,通过观察你的控制器是否会响应以下方法(按顺序):
create_params
<model_name>_params例如article_params(这是
在rails中命名你的param方法的默认约定)
Resource_params(可以在中指定的通用命名方法
每个控制器)
另外,load_and_authorize_resource现在可以接受param_method选项,在控制器中指定要运行的自定义方法来清理输入。
你可以将param_method选项与一个对应于将要被调用的方法名称的符号关联起来:
class ArticlesController < ApplicationController
load_and_authorize_resource param_method: :my_sanitizer
def create
if @article.save
# hurray
else
render :new
end
end
private
def my_sanitizer
params.require(:article).permit(:name)
end
end
来源:
https://github.com/CanCanCommunity/cancancan#33-strong-parameters
如果你在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']
对于使用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,看起来很有前途:
灿灿