新しいユーザーの作成時にActiveModel :: ForbiddenAttributesError


223

私はこのモデルを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]

このエラーを取り除く方法、または適切なユーザー登録フォームを作成する方法を教えてください。


2
ユーザーモデルにattr_accessible:password、:password_confirmation、:user_name、:email、:your-other-attributesを追加してみてください
Bachan Smruty

1
追加strong_parameter使用に宝石をattr_accessible
Wenbing Li

attr_accessibleを使用するための強力なパラメータ?!
Thiem Nguyen、2015

1
@BruceLiの意味:protected_attributes使用する宝石を追加しますattr_accessible
Stefan Magnuson

回答:


398

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

2
なぜこれが機能するのか、なぜこれが必要なのかについてのドキュメントはありますか?
DiverseAndRemote.com 2013

20
@OmarJackman機能はstrong_parametergem によって提供されます。Railsガイド:guides.rubyonrails.org/…でカバーされています。
Domon 2013

21
CanCanをRails 4.0で使用すると、この問題が発生する可能性があります。CanCanが更新されるまで、AntonTrappsのかなりクリーンな回避策を試してください。
mjnissim 2013

@mjnissimこれを別の回答として投稿してください。私は初めてそれを逃しましたが、それでも私にはたくさんの時間を節約しました。
ポールペッテンギル2013

64

CanCanをご利用の方へCanCan with 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

更新:

CanCanCanと呼ばれるCanCanの継続プロジェクトは次のとおりです。

CanCanCan


1
ありがとう!! CanCanCan(アクティブ)が解決されているか、このコードが必要ないのですか?
アドリアーノレゼンデ

私にとって、CanCanCanにはまだ問題があります。使用load_resourceまたは使用しないことでload_resource :except => :create問題は解決しました。元の答えをここで
Tun

24

強力なパラメータを回避する簡単な方法があります。次のように、パラメータを通常のハッシュに変換する必要があります。

unlocked_params = ActiveSupport::HashWithIndifferentAccess.new(params)

model.create!(unlocked_params)

もちろん、これは強力なパラメーターの目的に反しますが、私のような状況にある場合(私は自分のシステムの別の部分で許可されたパラメーターを自分で管理しています)、これで仕事が完了します。


レール6では機能しません。例外:unable to convert unpermitted parameters to hash
タイラー

20

ActiveAdminを使用している場合は、モデルレジスタブロックにもpermit_paramsがあることを忘れないでください。

ActiveAdmin.register Api::V1::Person do
  permit_params :name, :address, :etc
end

これらは、コントローラで設定する必要があります。

def api_v1_person_params
  params.require(:api_v1_person).permit(:name, :address, :etc)
end

そうしないと、エラーが発生します。

ActiveModel::ForbiddenAttributesError

18

CanCanCanを使用している場合

CanCanCanが正しいを見つけることができない場合、このエラーが発生します paramsメソッドを

以下のため:createのアクション、カンカンは、あなたのコントローラーが(順番に)以下のような方法に対応するかどうか見て消毒入力して新しいインスタンスを初期化しようとします。

  1. create_params
  2. <model_name>_params article_paramsなど(これは、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

ソース:https : //github.com/CanCanCommunity/cancancan#33-strong-parameters


3

または、保護属性gemを使用することもできますが、これは強力なパラメーターを要求する目的に反します。ただし、古いアプリをアップグレードする場合は、保護属性を使用すると、attr_accessibleを強力なパラメーターにリファクタリングできるようになるまで、簡単にアップグレードできます。


0

Rails 4を使用していて、このエラーが発生した場合、次のenumようなシンボルで定義した場合にモデルで使用していると、エラーが発生する可能性があります。

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']
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.