7

के साथ has_many नेस्टेड मॉडल बनाने के लिए संरक्षित विशेषताओं को बड़े पैमाने पर असाइन नहीं किया जा सकता है मैंने रेलस्कास्ट, एक अन्य नेस्टेड विशेषता वीडियो, बहुत सारे पोस्ट पोस्ट देखे हैं, और थोड़ी देर के लिए इसके साथ लड़े हैं, लेकिन मैं अभी भी नहीं कर सकता पता लगाओ। मुझे उम्मीद है कि यह कुछ छोटा है।डेविस

मैं दो मॉडल, User (वसीयत के द्वारा बनाई गई), और Locker (उर्फ, एक उत्पाद इच्छा सूची में शामिल है), और मैं एक User के लिए एक Locker बनाने के लिए जब वे साइन अप कोशिश कर रहा हूँ। मेरे लॉगिन फॉर्म में उनके नए Locker (जिसे :name कहा जाता है) के नाम के लिए एक फ़ील्ड है, जिसे मैं नए उपयोगकर्ता पंजीकरण पर बनाए गए लॉकर को असाइन करने का प्रयास कर रहा हूं। सभी मैं कभी भी है के साथ स्वागत कर रहा हूँ:

WARNING: Can't mass-assign protected attributes: locker

मैं अपने मॉडलों के दोनों में accepts_nested_attributes और attr_accesible के हर संयोजन की कोशिश की है, फिर भी अभी भी कुछ नहीं काम करता है। मैं लॉग कि यह द्वारा वसीयत # संसाधित विधि बनाने जा रहा है से देख सकते हैं, और मुझे पता वसीयत बहुत चालाक मेरी मॉडल बनाने के लिए मैं कैसे चाहते हैं :)

यहाँ मेरी दो मॉडल के प्रासंगिक बिट है नहीं है:

# user.rb  
class User < ActiveRecord::Base 
    attr_accessible :username, :email, :password, :password_confirmation, :remember_me, :locker_attributes 

    # Associations 
    has_many :lockers 
    has_many :lockups, :through => :lockers 

    # Model nesting access 
    accepts_nested_attributes_for :lockers 
end 

और

# locker.rb 
class Locker < ActiveRecord::Base 
    belongs_to :user 
    has_many :lockups 
    has_many :products, :through => :lockups 

    attr_accessible :name, :description 
end 

# lockers_controller.rb (create) 
    @locker = current_user.lockers.build(params[:locker]) 
    @locker.save 

मैं यह सोचते हैं रहा हूँ मैं वसीयत के create विधि ओवरराइड करने के लिए किसी भी तरह इस काम करने के लिए प्राप्त करने की आवश्यकता है, लेकिन मैं काफी रेल के लिए नया हूँ और ब्लैक बॉक्स "जादू" करने के लिए इस्तेमाल कर रहा हूँ सब की प्रकृति।

यदि कोई मेरी मदद कर सकता है, तो मैं अविश्वसनीय रूप से आभारी हूं। इस पर बहुत अधिक समय बिताया है :)

संपादित करें: मुझे एहसास हुआ कि मैंने अपनी समस्या में कुछ छोड़ दिया है। मेरे Locker मॉडल में तीन विशेषताएं हैं - name, description (अनिवार्य नहीं), और user_id इसे User पर लिंक करने के लिए। मेरे साइनअप फॉर्म को केवल name की आवश्यकता है, इसलिए मैं अपने नेस्टेड रूप में सभी विशेषताओं के माध्यम से लूप नहीं कर रहा हूं। क्या मेरे पास भी मेरे मुद्दे के साथ कुछ करना है?

संपादित 2: मुझे यह भी पता चला कि डेविस की RegistrationsController#create विधि को ओवरराइड करने के लिए, मुझे नहीं पता कि वहां क्या रखा जाए। डेविस की पूरी resource चीज मुझे समझ में नहीं आती है, और RegistrationsController के लिए उनके स्रोत कोड ब्राउज़ करने से मुझे बहुत मदद नहीं मिली।

और बोनस अंक के लिए: एक उपयोगकर्ता अमान्य डेटा के साथ लॉगिन प्रपत्र सबमिट करता है, Locker क्षेत्र हमेशा वापस खाली आता है, जबकि नियमित रूप से वसीयत के मैदान, उपयोगकर्ता नाम & ईमेल, में भर रहे हैं यह भी आसानी से तय किया जा सका। ? यदि हां, तो कैसे?

attr_accessible :locker_attributes 

बहुवचन होना चाहिए::

attr_accessible :lockers_attributes 

तो, nested_attributes उपयोग करने के लिए मानक तरीका है:

<%= form_for @user do |f| %> 
    <%# fields_for will iterate over all user.lockers and 
     build fields for each one of them using the block below, 
     with html name attributes like user[lockers_attributes][0][name]. 
     it will also generate a hidden field user[lockers_attributes][0][id] 
     if the locker is already persisted, which allows nested_attributes 
     to know if the locker already exists of if it must create a new one 
    %> 
    <% f.fields_for :lockers do |locker_fields| %> 
    <%= locker_fields.label  :name %> 
    <%= locker_fields.text_field :name %> 
    <% end %> 
<% end %> 

और आप नियंत्रक में

+0

आप लॉकर कैसे बना रहे हैं? क्या आप नियंत्रक कोड पोस्ट कर सकते हैं? – mihai

+0

मैंने अपने लॉकर्स # निर्माण विधि पोस्ट की, लेकिन मुझे नहीं लगता कि मेरा कोड भी उस पर पहुंच रहा है। मुझे लगता है कि डेविस उपयोगकर्ता बनाने और बस मेरे नियंत्रक कोड को छोड़ने की कोशिश कर रहा है। मुझसे गलती भी हो सकती है। –

+1

जो जांचना आसान होना चाहिए, बस नियंत्रक में 'डीबगर' लाइन जोड़ें और देखें कि यह वहां रुक गया है या नहीं। – mihai

उत्तर

1

मुझे किसी ने एक अधिक "रेल 4'y" strong attributes & साथ जिस तरह से कैसे वसीयत के sign_up_params (सभी डेटा मेरी साइनअप फॉर्म से आने वाले को पकड़ने के लिए) को ओवरराइड करने में समाधान यह पता लगाने में मदद की।

def sign_up_params 
    params.require(:user).permit(:username, :email, :password, :lockers_attributes) 
end 

Gemfile अलावा: gem 'strong_parameters'

मेरी user.rb फ़ाइल में attr_accessible बयान टिप्पणी करते हुए के बाद से जाहिरा तौर पर मजबूत मापदंडों attr_accessible घोषणाओं की आवश्यकता को समाप्त। अपने सभी की मदद के लिए

<%= l.input :name, :required => true, label: "Locker name", :placeholder => "Name your first locker" %>

धन्यवाद फिर से:

# attr_accessible :username, :email, :password, :password_confirmation, :lockers 

और/प्रपत्र प्रस्तुत करने से पहले एक लॉकर के निर्माण के एक सही तरीका: नेस्टेड प्रपत्र की शुरुआत में। मुझे एक सवाल पता है जैसे पूरे कोडबेस को देखे बिना जवाब देना मुश्किल है।

1

पहले, आप लिखने में कोई त्रुटि है :

def new 
    @user = User.new 
    @user.lockers.build 
end 

def create 
    # no need to use build here : params[:user] contains a 
    # :lockers_attributes key, which has an array of lockers attributes as value ; 
    # it gets assigned to the user using user.lockers_attributes=, 
    # a method created by nested_attributes 
    @user = User.new(params[:user]) 
end 

एक तरफ ध्यान दें के रूप में, आप अलग अलग तरीकों से नियंत्रक में नए उपयोगकर्ताओं के लिए नया लॉकर के निर्माण से बचने कर सकते हैं:

  • User पर फ़ैक्टरी विधि बनाने के लिए, या new ओवरराइड, या एक after_initialize कॉलबैक का उपयोग सुनिश्चित करने के लिए

    <% f.fields_for :lockers, f.object.lockers.new do |new_locker_fields| %> 
    
  • : instantiated हर नया उपयोगकर्ता fields_for के लिए एक विशिष्ट वस्तु पारित एक लॉकर स्वचालित रूप से बसाया

  • हो जाता है

+0

मैं पूरी तरह से आपके उत्तर की सराहना करता हूं, और मुझे लगता है कि आप सही रास्ते पर हैं (क्योंकि मैं समझता हूं कि आप इसके साथ कहां जा रहे हैं), लेकिन डेविस # निर्माण में जन-असाइनमेंट त्रुटि हो रही है, और मुझे नहीं पता कि वह कहां है है। मैं पहले से ही 'उपयोगकर्ता', 'लॉकर्स' इत्यादि बना सकता हूं, पंजीकरण के बाद उपयोगकर्ता के लिए स्वचालित रूप से लॉकर बनाने की यह नई सुविधा काम नहीं कर रही है। ऐसा लगता है कि मुझे डेविस में खोदने की ज़रूरत है, लेकिन मुझे नहीं पता कि कैसे। –

+0

ओह, यह समझ में नहीं आया कि समस्या डेविस से थी। क्या आप जानते थे कि आप डेविस नियंत्रकों को ओवरराइड कर सकते हैं? देखें [devise विकी] (https://github.com/plataformatec/devise#getting-started), अनुभाग "नियंत्रक कॉन्फ़िगर करना" –

+1

ओह, और जिस विधि को आपको ओवरराइड करने की आवश्यकता है वह 'उपयोगकर्ता' पर 'new_with_session' है। इसके बारे में एक [railscast] (http://railscasts.com/episodes/209-devise-revised?view=asciicast) है, लेकिन दुर्भाग्य से यह मुफ़्त नहीं है ... दूसरा विकल्प आपके नियंत्रक पर 'build_resource' को ओवरराइड करना है। –