नया उपयोगकर्ता बनाते समय ActiveModel :: ForbiddenAttributesError


223

रूबी में मेरे पास यह मॉडल है, लेकिन यह एक फेंकता है 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
, पासवर्ड:, password_confirmation:, user_name: जोड़ने attr_accessible के साथ प्रयास करें ई-मेल,: अपने-अन्य-जिम्मेदार बताते उपयोगकर्ता मॉडल में
बच्चन Smruty

1
जोड़े strong_parameter उपयोग करने के लिए मणि attr_accessible
वेनबिंग ली

attr_accessible का उपयोग करने के लिए मजबूत पैरामीटर ?!
थिएम गुयेन

1
मेरा मानना ​​है कि @ ब्रूसली का मतलब था: protected_attributesमणि को उपयोग में लाना attr_accessible
स्टीफन मैग्नसन

जवाबों:


398

मुझे लगता है कि आप रेल 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

20
@OmarJackman strong_parameterरत्न द्वारा कार्यक्षमता प्रदान की जाती है । यह रेल गाइड में शामिल है: guide.rubyonrails.org/…
डोमन

21
यदि वे रेल 4.0 के साथ कैनकन का उपयोग करते हैं तो लोग इसका अनुभव कर सकते हैं । जब तक कैनकन अपडेट नहीं हो जाता तब तक एंटोनट्रैप्स के बजाय स्वच्छ समाधान समाधान आज़माएं ।
mjnissim

@mjnissim क्या आप इसे एक अलग उत्तर के रूप में पोस्ट करेंगे? मैंने पहली बार इसे याद किया, लेकिन इसने मुझे एक टन समय बचा लिया।
पॉल पेटेंगेंग

64

Canan का उपयोग करने वालों के लिए । लोग इस का सामना किया जा सकता है अगर वे का उपयोग कैनकैन के साथ रेल 4+ । प्रयास करें AntonTrapps के बजाय स्वच्छ वैकल्पिक हल समाधान यहाँ तक कैनकैन अद्यतन हो जाता है:

में ApplicationController:

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

और संसाधन नियंत्रक में (उदाहरण के लिए नोटकंट्रोलर):

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

अपडेट करें:

यहाँ CanCanCan नामक CanCan के लिए एक निरंतरता परियोजना है , जो आशाजनक लगती है:

CanCanCan


1
धन्यवाद!! मेरे पास एक प्रश्न है, CanCanCan (सक्रिय) से हल किया गया है या इस कोड की आवश्यकता नहीं है?
एड्रियानो रेनेडे

मेरे लिए, CanCanCan अभी भी मुद्दा है। हल नहीं करने load_resourceया उपयोग load_resource :except => :createकरने से समस्या हल नहीं हुई । यहां
ट्यून

24

स्ट्रॉन्ग पैरामीटर्स से बचने का एक आसान तरीका है, आपको बस मापदंडों को एक नियमित हैश में बदलना होगा, जैसे:

unlocked_params = ActiveSupport::HashWithIndifferentAccess.new(params)

model.create!(unlocked_params)

यह निश्चित रूप से मजबूत मापदंडों के उद्देश्य को पराजित करता है, लेकिन अगर आप मेरी जैसी स्थिति में हैं (मैं अपने सिस्टम के किसी अन्य हिस्से में अनुमत परमर्स का अपना प्रबंधन कर रहा हूं) तो यह काम पूरा कर लेगा।


रेल 6 में काम नहीं करता है, अपवाद:unable to convert unpermitted parameters to hash
टायलर

20

ActiveAdmin का उपयोग करते समय यह न भूलें कि मॉडल रजिस्टर ब्लॉक में एक perm_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 सही पारमेस विधि नहीं ढूँढ सकता है तो आपको यह त्रुटि मिलेगी ।

के लिए :createकार्रवाई, कैनकैन देखकर स्वच्छ इनपुट के साथ एक नया उदाहरण प्रारंभ करने में यदि आपके नियंत्रक (क्रम में) निम्न विधियों का जवाब देंगे की कोशिश करेंगे:

  1. create_params
  2. <model_name>_params जैसे कि article_params (यह आपके परम विधि के नामकरण के लिए रेल में डिफ़ॉल्ट सम्मेलन है)
  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

वैकल्पिक रूप से आप संरक्षित गुण मणि का उपयोग कर सकते हैं , हालांकि यह मजबूत पैरे की आवश्यकता के उद्देश्य को हरा देता है। हालाँकि, यदि आप एक पुराने ऐप को अपग्रेड कर रहे हैं, तो प्रोटेक्टेड एट्रीब्यूट्स अपग्रेड करने के लिए एक आसान रास्ता प्रदान करते हैं, जब तक कि आप मजबूत पैरामेट्स के लिए attr_accessible को रिफैक्ट नहीं कर सकते।


0

यदि आप रेल 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']
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.