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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:14:38  来源:igfitidea点击:

ActiveModel::ForbiddenAttributesError when creating new user

ruby-on-railsrails-activerecord

提问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 的人。如果人们将CanCanRails 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 延续项目,看起来很有希望:

CanCanCan

罐头罐头

回答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 将尝试通过查看您的控制器是否会响应以下方法(按顺序)来使用经过消毒的输入初始化一个新实例:

  1. create_params
  2. <model_name>_paramssuch as article_params (this is the default convention in rails for naming your param method)
  3. resource_params(a generically named method you could specify in each controller)
  1. create_params
  2. <model_name>_params例如 article_params (这是 rails 中用于命名 param 方法的默认约定)
  3. 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']