2014-04-10 4 views
5

मैं सरल_फॉर्म का उपयोग करके मॉडल रिकॉर्ड को संपादित/अपडेट करने का प्रयास कर रहा हूं, लेकिन फॉर्म सीधे मॉडल फ़ील्ड को बदलने वाला नहीं है। इसके बजाय, मैं कुछ चेक_बॉक्स_टैग फ़ील्ड्स प्रदान करता हूं जो बताते हैं कि किन क्षेत्रों को बदलने की आवश्यकता है। नतीजतन, अद्यतन एक पैराम [: डिवाइस] हैश प्राप्त नहीं कर रहा है जिसे मैं गुणों को अद्यतन करने के लिए उपयोग कर सकता हूं। मैं इस हैश को बनाने का प्रयास कर रहा हूं, लेकिन जब मैं @ device.update_attributes (पैराम्स [: डिवाइस] जारी करता हूं) तो ForbiddenAttributesError प्राप्त कर रहा हूं।ActiveModel :: ForbiddenAttributesError को बनाए गए अपडेट_ट्रिब्यूट्स का उपयोग करके पैरामीटर हैश खुद

मेरा मानना ​​है कि मेरी मजबूत पैरामीटर सूची सही है। अगर मैं संपादन दृश्य में एक मॉडल फ़ील्ड (नाम) को संसाधित करने की अनुमति देता हूं, तो मुझे अपेक्षित पैराम [: डिवाइस] हैश प्राप्त होता है और सब कुछ काम करता है। अगर मैं उस फ़ील्ड को अक्षम करता हूं, क्योंकि मैं इसे बदलना नहीं चाहता, तो मुझे खुद को हैश बनाने की ज़रूरत है और मुझे त्रुटि मिलती है। जब मैंने बनाया हैश को देखा, तो यह मुझे दृश्य द्वारा पारित एक के बराबर दिखता है। मुझे समझ में नहीं आता कि यह क्यों विफल रहा है।

पर्यावरण रूबी 2.0.0, रूबीमाइन 6.3 के साथ विंडोज 8.1 पर रेल 4.1 है। ... < एक बार काम कर रहे ... सही स्वरूपण की जरूरत है>

<%= simple_form_for @device do |f| %> 
     <legend><%= controller.action_name.capitalize %> Device:</legend> 
     <%= f.input :name, disabled: true %> 
     <%= check_box_tag(:is_admin, 0, @device.admin?) %> 
     <%= label_tag(:is_admin, "Make admin?") %> 
     <%= check_box_tag(:chg_pwd) %> 
     <%= label_tag(:chg_pwd, "Change password?") %> 
     <%= f.button :submit %> 
<% end %> 

पैरामीटर:

रूप है [: डिवाइस] कि मैं प्राप्त मैं जब भेजा f.input: नाम, विकलांग: झूठे और व्यू को उत्पन्न करने की अनुमति दें [: ​​डिवाइस] है:

ActionController::Parameters (3 element(s)) 
"{"name"=>"D105", "password"=>"D105Dvgr", "password_confirmation"=>"D105Dvgr"}" 

और, सब कुछ काम करता है।

पैरामीटर [: डिवाइस] कि मैं बनाने है:

ActionController::Parameters (3 element(s)) 
"{"name"=>"D106", "password"=>"D106VdAd", "password_confirmation"=>"D106VdAd"}" 

और, मैं निषिद्ध गुण त्रुटि प्राप्त करते हैं, भले ही मैं दोनों के बीच कोई अंतर नहीं देखते हैं। ... < कोड रिफैक्टर्ड की जरूरत है, एक बार यह काम कर रहा है ...>

class DevicesController < ApplicationController 
    before_filter :authenticate_device! 

... other methods removed here ... 

    def edit 
    @device = Device.find(params[:id]) 
    # my_page = render_to_string controller: 'devices', action: 'edit', layout: "application" 
    end 

    def update 
    authorize! :update, @device, :message => 'Not authorized as an administrator.' 
    @device = Device.find(params[:id]) 
    pwd_msg = "" 
    if params[:chg_pwd] 
     pwd_gen = @device.device + SecureRandom.urlsafe_base64(15).tr('lIO0=_\-', 'sxyzEUM').first(4) 
     params[:device] = {name: @device.name} if params[:device].nil? 
     params[:device][:password] = pwd_gen 
     params[:device][:password_confirmation] = pwd_gen 
     pwd_msg = ", new password is #{pwd_gen}" 
    end 
    if @device.update_attributes(params[:device]) 
     params[:is_admin] ? @device.add_role(:admin) : @device.remove_role(:admin) 
     flash[:notice] = ["Device updated" + pwd_msg] 
     redirect_to devices_path 
    else 
     @device.errors.messages.each do |key, value| 
     flash[:alert] = ["Unable to update device"] 
     @device.errors.messages.each do |key, value| 
      flash[:alert] << key.to_s.capitalize + " " + value[0] 
     end 
     end 
     redirect_to devices_path 
    end 
    end 

    private 

    def device_params 
    params.require(:device).permit(:device, :name, :email, :password, :password_confirmation, :encrypted_password, :salt, :role_ids, :is_admin, :chg_pwd) # TODO minimize when update is working 
    end 

end 

मॉडल है:

अद्यतन है

class Device < ActiveRecord::Base 

    rolify 
    devise :database_authenticatable, :rememberable, :trackable, :validatable 

    validates :device, 
      presence: true, 
      length: {minimum: 4 }, 
      uniqueness: {case_sensitive: false } 
    validates :name, 
      presence: true 

    def remember_me 
    true unless self.admin? 
    end 

    def admin 
    self.add_role :admin 
    end 

    def not_admin 
    self.remove_role :admin 
    end 

    def admin? 
    self.has_role? :admin 
    end 
    def device? 
    self.has_role? :device 
    end 
    def vip? 
    self.has_role? :vip 
    end 

    def login=(login) 
    @login = login 
    end 
    def login 
    @login || self.device || self.email 
    end 

    def self.find_first_by_auth_conditions(warden_conditions) 
    conditions = warden_conditions.dup 
    if login = conditions.delete(:login) # Note one equal sign. Strange but true. 
     where(conditions).where(["lower(device) = :value OR lower(email) = :value", { :value => login.downcase }]).first 
    else 
     where(conditions).first 
    end 
    end 

end 

नई जानकारी: मैं जानकारी प्रदान करने के उपेक्षित मेरे पास एप्लिकेशन नियंत्रक में है।

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

मैं ने पाया है कि प्रस्तावित समाधान का उपयोग:

@device.update_attributes(device_params) 

एक मॉडल है, तो काम नहीं करता है एंटोन Trapp से इस सुधार में अभी तक पूरी तरह रेल नहीं कर रहे हैं कि 4 संगत जवाहरात के लिए मजबूत मापदंडों संभालती क्षेत्र अद्यतन किया गया है। परिणाम "param नहीं मिला: डिवाइस" है। यदि कोई मॉडल फ़ील्ड अपडेट नहीं होता है तो यह काम करता है। तो, पूरा मुद्दा सवाल पूछता है कि वास्तव में क्या गलत है।

उत्तर

1

ठीक मॉडल के लिए attr_accessor जैसे क्षेत्रों को जोड़ने के लिए किया गया था, लेकिन डेटाबेस नहीं, ताकि यह फ़ॉर्म के भीतर सही ढंग से उपयोग किया जा सके।

attr_accessor :is_admin, :chg_pwd 

और फिर करने के लिए दृश्य को संशोधित: एंटोन Trapp से आवेदन नियंत्रक कोड के कारण

<%= simple_form_for @device do |f| %> 
    <legend><%= controller.action_name.capitalize %> Device:</legend> 
    <%= f.input :name, disabled: true %> 
    <%= f.input :is_admin, as: :boolean, checked_value: true, unchecked_value: false %> 
    <%= f.input :chg_pwd, as: :boolean, checked_value: true, unchecked_value: false %> 
    <%= f.button :submit %> 
<% end %> 

फिर,:

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

मैं डिवाइस नियंत्रक में फ़ील्ड अपडेट कर रहा था निम्नानुसार है:

@device.update_attributes(params[:device]) 
3

DevicesController#update कार्रवाई में, बदल

@device.update_attributes(params[:device]) 

आप Rails 4.1 उपयोग कर रहे हैं के रूप में

@device.update_attributes(device_params) 

के लिए, आपको विशेषताएं हैं जिन्हें आप सम्मिलित करने के लिए/डेटाबेस में अद्यतन चाहते हैं श्वेतसूची में डालना होगा।आप उन्हें अनुमति देने के बिना update_attributes विधि करने के लिए सीधे गुण पारित कर के रूप में आप ActiveModel::ForbiddenAttributesError

अद्यतन प्राप्त

param not found: device हल करने के लिए:

def device_params 
    if params[:device] 
     params.require(:device).permit(:device, :name, :email, :password, :password_confirmation, :encrypted_password, :salt, :role_ids, :is_admin, :chg_pwd) # TODO minimize when update is working 
    end 
    end 
+0

ठीक है, परिवर्तन कुल समझ और काम करता है। मुझे अभी भी आश्चर्य है, हालांकि, मॉडल मॉडल में शामिल होने पर यह क्यों काम करता था? क्या आप जानते हैं कि? धन्यवाद ... –

+0

'मॉडल मॉडल में शामिल होने पर यह क्यों काम करता था?' मतलब है? कौन सा मॉडल फ़ील्ड? क्या आपका मतलब यह कोड किसी भी मामले में काम करता है? –

+0

संपादन दृश्य में, यदि मैं "f.input: name, अक्षम: false" का उपयोग करता हूं, तो पैरा [: डिवाइस] पैराम [: डेविस] [: name] सेट के साथ अद्यतन कार्रवाई में भेजा जाता है। उस स्थिति में, अपडेट एक्शन के रूप में काम किया था। यदि, इसके बजाय, मैं "f.input: name, disabled: true" का उपयोग करता हूं, ताकि नाम फ़ील्ड को नहीं बदला जा सके, पैराम्स [: डिवाइस] शून्य से है। Update_attributes के क्रम में, मैंने दिखाए गए पैरा [: डिवाइस] को बनाया है। दोनों हैंश बराबर हैं। लेकिन, मैंने बनाया हैश पर फोर्बिडन एट्रिब्यूट एरर प्राप्त किया है, भले ही मेरे लिए बनाया गया संपादन दृश्य @ device.update_attributes (पैराम्स [: डिवाइस]) का उपयोग करके काम करता है। –

संबंधित मुद्दे