ActiveModel :: Yeni kullanıcı oluştururken ForbiddenAttributesError


223

Ruby'de bu model var ama 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

bu eylemi yürüttüğümde

  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

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

Lütfen bu hatadan nasıl kurtulacağımı veya uygun bir kullanıcı kayıt formu oluşturacağımı söyleyebilir misiniz?


2
Kullanıcı modelinde attr_accessible: password,: password_confirmation,: user_name,: email,: diğer özelliklerinizi
eklemeyi deneyin

1
Ekle strong_parameter kullanım için gem attr_accessible .
Wenbing Li

attr_accessible kullanmak için güçlü parametreler ?!
Thiem Nguyen

1
@BruceLi demek istedim: Kullanmak için protected_attributesmücevher ekleyin attr_accessible.
Stefan Magnuson

Yanıtlar:


398

Sanırım Rails 4 kullanıyorsunuz. Gerekli ise, gerekli parametreler gerektiği gibi işaretlenmelidir.

Bunu şu şekilde yapmak isteyebilirsiniz:

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
Bunun neden işe yaradığına veya neden gerekli olduğuna dair herhangi bir belge var mı?
DiverseAndRemote.com

20
@OmarJackman İşlevsellik strong_parametermücevher tarafından sağlanır . Raylar Kılavuzları kapsamındadır: guides.rubyonrails.org/… .
Domon

21
RaC 4.0 ile CanCan kullanıyorsa insanlar bunu yaşıyor olabilir . CanCan güncellenene kadar AntonTrapps'ın oldukça temiz geçici çözümünü deneyin .
mjnissim

@mjnissim Lütfen bunu ayrı bir cevap olarak gönderir misiniz? İlk kez kaçırdım, ama yine de beni bir ton kurtardı.
Paul Pettengill

64

CanCan kullananlar için . İnsanlar CanCan'ı Rails 4+ ile kullanıyorsa bunu yaşıyor olabilirler . CanCan güncellenene kadar AntonTrapps'ın oldukça temiz geçici çözümünü burada deneyin :

İçinde ApplicationController:

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

ve kaynak denetleyicisinde (örneğin NoteController):

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

Güncelleme:

CanCan için CanCanCan adı verilen ve umut vadeden bir devam projesi :

cancancan


1
Teşekkürler!! Bir sorum var, CanCanCan (aktif) ile çözüldü ya da bu koda gerek yok?
Adriano Resende

Benim için, CanCanCan hala sorunu var. Kullanmamak load_resourceveya kullanmak load_resource :except => :createsorunu çözdü. Buradaki
Tun

24

Güçlü Parametrelerden kaçınmanın daha kolay bir yolu var, parametreleri normal bir hash'a dönüştürmeniz yeterlidir:

unlocked_params = ActiveSupport::HashWithIndifferentAccess.new(params)

model.create!(unlocked_params)

Bu elbette güçlü parametrelerin amacını yener, ancak benimki gibi bir durumdaysanız (sistemimin başka bir bölümünde izin verilen params yönetimini yapıyorum) bu işi halledecektir.


Raylar 6'da çalışmaz, istisna:unable to convert unpermitted parameters to hash
Tyler

20

ActiveAdmin kullanıyorsanız, model kayıt bloğunda bir permit_params olduğunu da unutmayın:

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

Bunların kontrolördekilerle birlikte ayarlanması gerekir:

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

Aksi takdirde hatayı alırsınız:

ActiveModel::ForbiddenAttributesError

18

CanCanCan kullananlar için :

CanCanCan doğru params yöntemini bulamazsa bu hatayı alırsınız .

İçin :createeylem, CanCan Denetleyiciniz (sırayla) aşağıdaki yöntemlerden cevap verecektir eğer görerek sterilize girişi olan yeni bir örneğini başlatmak için çalışacağız:

  1. create_params
  2. <model_name>_params article_params (bu, param yönteminizi adlandırmak için raylardaki varsayılan kuraldır)
  3. resource_params (her denetleyicide belirleyebileceğiniz genel olarak adlandırılmış bir yöntem)

Ayrıca, load_and_authorize_resourceartık param_methodgirişi sanitize etmek için denetleyicide özel bir yöntem belirleme seçeneğini de alabilir .

param_methodSeçeneği, çağrılacak bir yöntemin adına karşılık gelen bir sembolle ilişkilendirebilirsiniz :

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

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


3

Alternatif olarak, Korumalı Özellikler gemisini kullanabilirsiniz , ancak bu, güçlü parametreler gerektirme amacını ortadan kaldırır. Ancak daha eski bir uygulamayı yeni sürüme geçiriyorsanız, Protected Attributes, attr_accessible ürününü güçlü parametrelere yeniden düzenleyebileceğiniz zamana kadar yükseltmek için kolay bir yol sağlar.


0

Rails 4 üzerindeyseniz ve bu hatayı alırsanız, bunun enumgibi sembollerle tanımladıysanız modelde kullanıyorsanız bu olabilir:

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

Form, telsiz seçici dize parametresi olarak geçecektir. Benim durumumda olan buydu. Basit düzeltme, enumsemboller yerine dizelere geçmek

enum preferred_phone: %w[home_phone mobile_phone work_phone]
# or more verbose
enum preferred_phone: ['home_phone', 'mobile_phone', 'work_phone']
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.