Ruby-on-rails 创建新用户时的 ActiveModel::ForbiddenAttributesError
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17335329/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ActiveModel::ForbiddenAttributesError when creating new user
提问by LeMike
I have this model in Ruby but it throws a ActiveModel::ForbiddenAttributesError
我在 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
when I run this action
当我运行此操作时
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
on ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux].
上ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]。
Can you please tell me how to get rid of this error or establish a proper user registration form?
你能告诉我如何摆脱这个错误或建立一个正确的用户注册表吗?
回答by Domon
I guess you are using Rails 4. If so, the needed parameters must be marked as required.
我猜您正在使用 Rails 4。如果是这样,则必须将所需的参数标记为必需。
You might want to do it like this:
你可能想这样做:
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
回答by mjnissim
For those using CanCan. People might be experiencing this if they use CanCanwith Rails 4+. Try AntonTrapps'srather clean workaround solution hereuntil CanCan gets updated:
对于那些使用 CanCan 的人。如果人们将CanCan与Rails 4+一起使用,他们可能会遇到这种情况。在这里尝试AntonTrapps相当干净的解决方案,直到 CanCan 更新:
In the ApplicationController:
在ApplicationController:
before_filter do
resource = controller_name.singularize.to_sym
method = "#{resource}_params"
params[resource] &&= send(method) if respond_to?(method, true)
end
and in the resource controller (for example NoteController):
并在资源控制器(例如 NoteController)中:
private
def note_params
params.require(:note).permit(:what, :ever)
end
Update:
更新:
Here's a continuation project for CanCan called CanCanCan, which looks promising:
这是一个名为CanCanCan 的CanCan 延续项目,看起来很有希望:
回答by Wilker Lucio
There is an easier way to avoid the Strong Parameters at all, you just need to convert the parameters to a regular hash, as:
有一种更简单的方法可以完全避免强参数,您只需要将参数转换为常规哈希,如下所示:
unlocked_params = ActiveSupport::HashWithIndifferentAccess.new(params)
model.create!(unlocked_params)
This defeats the purpose of strong parameters of course, but if you are in a situation like mine (I'm doing my own management of allowed params in another part of my system) this will get the job done.
这当然违背了强参数的目的,但是如果您处于像我这样的情况(我正在我系统的另一部分对允许的参数进行自己的管理),这将完成工作。
回答by StuR
If using ActiveAdmin don't forget that there is also a permit_params in the model register block:
如果使用 ActiveAdmin,请不要忘记模型寄存器块中还有一个 permit_params:
ActiveAdmin.register Api::V1::Person do
permit_params :name, :address, :etc
end
These need to be set along with those in the controller:
这些需要与控制器中的那些一起设置:
def api_v1_person_params
params.require(:api_v1_person).permit(:name, :address, :etc)
end
Otherwise you will get the error:
否则你会得到错误:
ActiveModel::ForbiddenAttributesError
回答by Andreas
For those using CanCanCan:
对于那些使用CanCanCan 的人:
You will get this error if CanCanCan cannot find the correct params method.
如果 CanCanCan 找不到正确的params 方法,您将收到此错误。
For the :createaction, CanCan will try to initialize a new instance with sanitized input by seeing if your controller will respond to the following methods (in order):
对于该:create操作,CanCan 将尝试通过查看您的控制器是否会响应以下方法(按顺序)来使用经过消毒的输入初始化一个新实例:
create_params<model_name>_paramssuch as article_params (this is the default convention in rails for naming your param method)resource_params(a generically named method you could specify in each controller)
create_params<model_name>_params例如 article_params (这是 rails 中用于命名 param 方法的默认约定)resource_params(您可以在每个控制器中指定的通用命名方法)
Additionally, load_and_authorize_resourcecan now take a param_methodoption to specify a custom method in the controller to run to sanitize input.
此外,load_and_authorize_resource现在可以param_method选择在控制器中指定一个自定义方法来运行以清理输入。
You can associate the param_methodoption with a symbol corresponding to the name of a method that will get called:
您可以将该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
source: https://github.com/CanCanCommunity/cancancan#33-strong-parameters
来源:https: //github.com/CanCanCommunity/cancancan#33-strong-parameters
回答by Brian Dear
Alternatively you can use the Protected Attributes gem, however this defeats the purpose of requiring strong params. However if you're upgrading an older app, Protected Attributes does provide an easy pathway to upgrade until such time that you can refactor the attr_accessible to strong params.
或者,您可以使用Protected Attributes gem,但这违背了要求强参数的目的。但是,如果您要升级较旧的应用程序,受保护的属性确实提供了一种简单的升级途径,直到您可以将 attr_accessible 重构为强参数为止。
回答by lacostenycoder
If you are on Rails 4 and you get this error, it could happen if you are using enumon the model if you've defined with symbols like this:
如果您在 Rails 4 上遇到此错误,并且enum在模型上使用时可能会发生这种情况,前提是您已使用以下符号进行定义:
class User
enum preferred_phone: [:home_phone, :mobile_phone, :work_phone]
end
The form will pass say a radio selector as a string param. That's what happened in my case. The simple fix is to change enumto strings instead of symbols
该表单将说一个单选选择器作为字符串参数传递。这就是我的情况。简单的解决方法是更改enum为字符串而不是符号
enum preferred_phone: %w[home_phone mobile_phone work_phone]
# or more verbose
enum preferred_phone: ['home_phone', 'mobile_phone', 'work_phone']

