242 votes

ActiveModel::ForbiddenAttributesError lors de la création d'un nouvel utilisateur

J'ai ce modèle en Ruby mais il jette une 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

quand je lance cette 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

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

Pouvez-vous me dire comment me débarrasser de cette erreur ou établir un formulaire d'inscription correct pour les utilisateurs ?

2 votes

Essayez d'ajouter attr_accessible :password, :password_confirmation,:user_name, :email, :your-other-attributes dans le modèle User

1 votes

Ajouter paramètre fort la pierre précieuse à utiliser attr_accessible .

0 votes

Paramètres forts pour utiliser attr_accessible ?!

432voto

Domon Points 2681

Je suppose que vous utilisez Rails 4. Si c'est le cas, les paramètres nécessaires doivent être marqués comme obligatoires.

Vous pourriez le faire comme ça :

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 votes

Existe-t-il une documentation expliquant pourquoi cela fonctionne ou pourquoi cela est nécessaire ?

21 votes

@OmarJackman La fonctionnalité est fournie par l' strong_parameter pierre précieuse. Il est couvert dans les Guides Rails : guides.rubyonrails.org/ .

21 votes

Les gens peuvent rencontrer ce problème s'ils utilisent CanCan avec Rails 4.0. Essayez AntonTrapps solution de contournement plutôt propre jusqu'à ce que CanCan soit mis à jour.

65voto

mjnissim Points 1734

Pour ceux qui utilisent CanCan . Cela peut arriver si l'on utilise CanCan con Rails 4+. . Essayez AntonTrapps solution de contournement plutôt propre aquí jusqu'à ce que CanCan soit mis à jour :

Dans le ApplicationController :

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

et dans le contrôleur de ressources (par exemple NoteController) :

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

Mise à jour :

Voici un projet de continuation pour CanCan appelé CanCanCan qui semble prometteur :

CanCanCan

1 votes

Merci ! J'ai une question, avec CanCanCan (actif) est résolu ou pas besoin de ce code ?

0 votes

Pour moi, CanCanCan a toujours le problème. N'utilisant pas load_resource ou utiliser load_resource :except => :create a résolu le problème. Consultez la réponse originale aquí

28voto

Andreas Points 320

Pour ceux qui utilisent CanCanCan :

Vous obtiendrez cette erreur si CanCanCan ne peut pas trouver le bon code d'accès. méthode params .

Pour le :create CanCan essaiera d'initialiser une nouvelle instance avec des données aseptisées en vérifiant si votre contrôleur répond aux méthodes suivantes (dans l'ordre) :

  1. create_params
  2. <model_name>_params comme article_params (c'est convention par défaut dans rails pour nommer votre méthode param)
  3. resource_params (une méthode au nom générique que vous pouvez spécifier dans le champ chaque contrôleur)

En outre, load_and_authorize_resource peut maintenant prendre un param_method pour spécifier une méthode personnalisée dans le contrôleur à exécuter pour assainir l'entrée.

Vous pouvez associer le param_method avec un symbole correspondant au nom d'une méthode qui sera appelée :

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

25voto

Wilker Lucio Points 113

Il existe un moyen plus simple d'éviter les paramètres forts, il suffit de convertir les paramètres en un hachage ordinaire, comme :

unlocked_params = ActiveSupport::HashWithIndifferentAccess.new(params)

model.create!(unlocked_params)

Bien sûr, cela va à l'encontre de l'objectif des paramètres forts, mais si vous êtes dans une situation comme la mienne (je fais ma propre gestion des paramètres autorisés dans une autre partie de mon système), cela fera l'affaire.

24voto

StuR Points 3542

Si vous utilisez ActiveAdmin, n'oubliez pas qu'il existe également un permit_params dans le bloc de registre du modèle :

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

Ils doivent être définis en même temps que ceux du contrôleur :

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

Sinon, vous obtiendrez l'erreur :

ActiveModel::ForbiddenAttributesError

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X