ActiveModel :: ForbiddenAttributesError beim Erstellen eines neuen Benutzers

223

Ich habe dieses Modell in Ruby, aber es wirft ein 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

wenn ich diese Aktion ausführe

  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

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

Können Sie mir bitte sagen, wie ich diesen Fehler beseitigen oder ein ordnungsgemäßes Benutzerregistrierungsformular erstellen kann?

LeMike
quelle
2
Versuchen Sie, attr_accessible: password ,: password_confirmation ,: user_name ,: email ,: your-other-attribute im Benutzermodell
hinzuzufügen
1
Fügen Sie den Edelstein strong_parameter hinzu , um attr_accessible zu verwenden .
Wenbing Li
Starke Parameter für attr_accessible?!
Thiem Nguyen
1
Ich glaube, @BruceLi meinte: Füge den protected_attributeszu verwendenden Edelstein hinzu attr_accessible.
Stefan Magnuson

Antworten:

398

Ich denke, Sie verwenden Rails 4. Wenn ja, müssen die erforderlichen Parameter als erforderlich markiert werden.

Vielleicht möchten Sie es so machen:

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
Domon
quelle
2
Gibt es eine Dokumentation darüber, warum dies funktioniert oder warum dies erforderlich ist?
DiverseAndRemote.com
20
@OmarJackman Die Funktionalität wird vom strong_parameterJuwel bereitgestellt . Es wird in Rails Guides behandelt : guides.rubyonrails.org/… .
Domon
21
Menschen können dies erleben, wenn sie CanCan mit Rails 4.0 verwenden. Probieren Sie die ziemlich saubere Problemumgehungslösung von AntonTrapps aus, bis CanCan aktualisiert wird.
mjnissim
@mjnissim Würden Sie dies bitte als separate Antwort posten? Ich habe es das erste Mal verpasst, aber es hat mir trotzdem eine Menge Zeit gespart.
Paul Pettengill
64

Für diejenigen, die CanCan verwenden . Menschen können dies erleben, wenn sie CanCan mit Rails 4+ verwenden . Probieren Sie hier die ziemlich saubere Problemumgehungslösung von AntonTrapps aus , bis CanCan aktualisiert wird:

In der ApplicationController:

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

und im Ressourcencontroller (zum Beispiel NoteController):

private
def note_params
  params.require(:note).permit(:what, :ever)
end

Aktualisieren:

Hier ist ein Fortsetzungsprojekt für CanCan namens CanCanCan , das vielversprechend aussieht:

CanCanCan

mjnissim
quelle
1
Vielen Dank!! Ich habe eine Frage, mit der CanCanCan (aktiv) gelöst ist oder diesen Code nicht benötigt?
Adriano Resende
Für mich hat CanCanCan immer noch das Problem. Nicht verwenden load_resourceoder verwenden load_resource :except => :createlöste das Problem. Überprüfen Sie die ursprüngliche Antwort hier
Tun
24

Es gibt eine einfachere Möglichkeit, die starken Parameter überhaupt zu vermeiden. Sie müssen lediglich die Parameter in einen regulären Hash konvertieren:

unlocked_params = ActiveSupport::HashWithIndifferentAccess.new(params)

model.create!(unlocked_params)

Dies macht natürlich den Zweck starker Parameter zunichte, aber wenn Sie sich in einer Situation wie meiner befinden (ich verwalte die zulässigen Parameter in einem anderen Teil meines Systems selbst), wird dies die Arbeit erledigen.

Wilker Lucio
quelle
Funktioniert nicht in Schienen 6, Ausnahme:unable to convert unpermitted parameters to hash
Tyler
20

Wenn Sie ActiveAdmin verwenden, vergessen Sie nicht, dass sich im Modellregisterblock auch allow_params befindet:

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

Diese müssen zusammen mit denen in der Steuerung eingestellt werden:

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

Andernfalls erhalten Sie die Fehlermeldung:

ActiveModel::ForbiddenAttributesError
StuR
quelle
18

Für diejenigen, die CanCanCan verwenden :

Sie erhalten diesen Fehler, wenn CanCanCan die richtige params-Methode nicht finden kann .

Für die :createAktion versucht CanCan, eine neue Instanz mit bereinigten Eingaben zu initialisieren, indem überprüft wird, ob Ihr Controller (in der angegebenen Reihenfolge) auf die folgenden Methoden reagiert:

  1. create_params
  2. <model_name>_params wie article_params (dies ist die Standardkonvention in Rails zum Benennen Ihrer param-Methode)
  3. resource_params (Eine generisch benannte Methode, die Sie in jedem Controller angeben können.)

Darüber hinaus load_and_authorize_resourcekann jetzt eine param_methodOption zum Angeben einer benutzerdefinierten Methode im Controller verwendet werden, die ausgeführt werden soll, um die Eingabe zu bereinigen.

Sie können die param_methodOption einem Symbol zuordnen, das dem Namen einer Methode entspricht, die aufgerufen wird:

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

Quelle: https://github.com/CanCanCommunity/cancancan#33-strong-parameters

Andreas
quelle
3

Alternativ können Sie den Edelstein "Geschützte Attribute" verwenden. Dies macht jedoch den Zweck zunichte, starke Parameter zu benötigen. Wenn Sie jedoch eine ältere App aktualisieren, bietet Protected Attributes einen einfachen Weg zum Aktualisieren, bis Sie attr_accessible für starke Parameter umgestalten können.

Brian Lieber
quelle
0

Wenn Sie sich auf Rails 4 befinden und diese Fehlermeldung angezeigt wird, kann dies passieren, wenn Sie enumdas Modell verwenden, wenn Sie folgende Symbole definiert haben:

class User
  enum preferred_phone: [:home_phone, :mobile_phone, :work_phone]
end

Das Formular wird beispielsweise einen Funkwähler als Zeichenfolgenparameter übergeben. Das ist in meinem Fall passiert. Die einfache Lösung besteht darin enum, anstelle von Symbolen zu Zeichenfolgen zu wechseln

enum preferred_phone: %w[home_phone mobile_phone work_phone]
# or more verbose
enum preferred_phone: ['home_phone', 'mobile_phone', 'work_phone']
Lacostenycoder
quelle