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

j'ai Ce modèle en rubis mais il lance un 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-zd-.]+.[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

lorsque j'exécute 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 svp me dire comment me débarrasser de cette erreur ou d'établir un formulaire d'inscription?

207
demandé sur Vertexwahn 2013-06-27 09:41:33

7 réponses

je suppose que vous utilisez des Rails 4. Si oui, les paramètres nécessaires doivent être marquées comme obligatoires.

vous pourriez vouloir le faire comme ceci:

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
374
répondu Domon 2013-06-27 06:21:16

Pour ceux qui utilisent CanCan . Les gens pourraient éprouver cela s'ils utilisent CanCan avec Rails 4+ . Essayez AntonTrapps plutôt propre solution de rechange ici jusqu'à ce CanCan est 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

63
répondu mjnissim 2015-03-19 01:12:23

il y a une façon plus facile d'éviter les paramètres forts du tout, vous avez juste besoin de convertir les paramètres à un hachage régulier, comme:

unlocked_params = ActiveSupport::HashWithIndifferentAccess.new(params)

model.create!(unlocked_params)

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

23
répondu Wilker Lucio 2015-04-14 18:07:11

si vous utilisez ActiveAdmin n'oubliez pas qu'il y a aussi un permit_params dans le bloc de registre modèle:

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

ceux-ci doivent être réglés avec 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
19
répondu StuR 2014-03-26 17:55:40

pour ceux qui utilisent CanCanCan :

vous obtiendrez cette erreur si CanCanCan ne peut trouver la bonne méthode params .

pour l'action :create , CanCan va essayer d'initialiser une nouvelle instance avec des entrées aseptisées en voyant si votre contrôleur va répondre aux méthodes suivantes (dans l'ordre):

  1. create_params
  2. <model_name>_params comme article_params (ceci est la convention par défaut dans les rails pour nommer votre méthode param)
  3. resource_params chaque contrôleur)

de plus, load_and_authorize_resource peut maintenant prendre une option param_method pour spécifier une méthode personnalisée dans le contrôleur pour exécuter l'entrée sanitize.

vous pouvez associer l'option param_method avec un symbole correspondant à la 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#strong-parameters

9
répondu Andreas 2017-02-06 14:42:27

alternativement, vous pouvez utiliser le attributs protégés gem , mais cela va à l'encontre de l'objectif d'exiger des params forts. Cependant, si vous mettez à niveau une application plus ancienne, les attributs protégés fournissent une voie facile à mettre à niveau jusqu'à ce que vous puissiez modifier l'attractif_accessible en params forts.

3
répondu Brian Dear 2013-07-22 02:30:15

Bonjour dans mon cas, l'erreur est corrigée, mais obtenir un résultat vide est une base de données.

 def create
@worklog = Worklog.new(user_params)
@worklog.day = Date.today
@worklog.week = Date.today.strftime("%W").to_i
@worklog.author = User.current
@worklog.save
redirect_to worklogs_path()
 end

 def user_params
params.require(:worklog).permit(:utf8, :authenticity_token, {:worklog => [:typee, :do, :todo, :feel, :plan_done, :plan, :week_feel, :score, :good, :nogood]}, :commit)

}

mon plugin original est https://github.com/IceskYsl/worklogs

-1
répondu Dipen Patel 2017-01-11 16:42:53