创建新用户时ActiveModel :: ForbiddenAttributesError

LeM*_*ike 219 ruby-on-rails rails-activerecord

我在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
Run Code Online (Sandbox Code Playgroud)

当我运行这个动作

  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
Run Code Online (Sandbox Code Playgroud)

ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux].

你能告诉我如何摆脱这个错误或建立一个合适的用户注册表吗?

Dom*_*mon 392

我猜您正在使用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
Run Code Online (Sandbox Code Playgroud)

  • 如果人们使用**CanCan**和Rails 4.0,人们可能会遇到这种情况.试试[AntonTrapps的(https://github.com/ryanb/cancan/issues/835#issuecomment-18663815),而干净的解决方法解决方案,直到惨惨得到更新. (20认同)
  • @OmarJackman该功能由`strong_parameter` gem提供.它包含在Rails指南中:http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters. (18认同)
  • 是否有任何文件说明为何有效或为何需要? (2认同)

mjn*_*sim 64

对于那些使用CanCan的人.如果人们使用CanCanRails 4+,人们可能会遇到这种情况.尝试使用AntonTrapps相当干净的解决方案,直到CanCan得到更新:

ApplicationController:

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

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

private
def note_params
  params.require(:note).permit(:what, :ever)
end
Run Code Online (Sandbox Code Playgroud)

更新:

这是CanCan的一个名为CanCanCan的延续项目,看起来很有希望:

CanCanCan


Wil*_*cio 23

有一种更简单的方法可以避免强参数,您只需要将参数转换为常规哈希,如下所示:

unlocked_params = ActiveSupport::HashWithIndifferentAccess.new(params)

model.create!(unlocked_params)
Run Code Online (Sandbox Code Playgroud)

这当然会破坏强参数的目的,但是如果你处于像我这样的情况(我正在自己管理系统的另一部分允许的参数),这将完成工作.

  • 在 Rails 6 中不起作用,异常:“无法将未经允许的参数转换为散列” (3认同)

Stu*_*tuR 20

如果使用ActiveAdmin,请不要忘记模型寄存器块中还有permit_params:

ActiveAdmin.register Api::V1::Person do
  permit_params :name, :address, :etc
end
Run Code Online (Sandbox Code Playgroud)

这些需要与控制器中的那些一起设置:

def api_v1_person_params
  params.require(:api_v1_person).permit(:name, :address, :etc)
end
Run Code Online (Sandbox Code Playgroud)

否则你会收到错误:

ActiveModel::ForbiddenAttributesError
Run Code Online (Sandbox Code Playgroud)


And*_*eas 15

对于使用CanCanCan的人:

如果CanCanCan找不到正确的params方法,您将收到此错误.

对于该:create操作,CanCan将尝试通过查看您的控制器是否将响应以下方法(按顺序)来初始化具有已清理输入的新实例:

  1. create_params
  2. <model_name>_params 例如article_params(这是rails中用于命名param方法的默认约定)
  3. 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
Run Code Online (Sandbox Code Playgroud)

来源:https: //github.com/CanCanCommunity/cancancan#strong-parameters

  • 谢谢您,先生,这非常有帮助 (2认同)