2009-06-01 12 views
69

में विफल रहा है, मैं अपने रेल मॉडल में से एक में accepts_nested_attributes_for का उपयोग कर रहा हूं, और मैं माता-पिता बनाने के बाद बच्चों को सहेजना चाहता हूं।accepts_nested_attributes_for बच्चे एसोसिएशन सत्यापन

फॉर्म पूरी तरह से काम करता है, लेकिन सत्यापन विफल हो रहा है।

class Project < ActiveRecord::Base 
    has_many :tasks 
    accepts_nested_attributes_for :tasks 
end 

class Task < ActiveRecord::Base 
    belongs_to :project 

    validates_presence_of :project_id 
    validates_associated :project 
end 

और मैं चला रहा हूँ: के लिए सादगी की खातिर निम्नलिखित कल्पना

Project.create!(
    :name => 'Something', 
    :task_attributes => [ { :name => '123' }, { :name => '456' } ] 
) 

परियोजना मॉडल को सहेजने पर, मान्यता कार्यों पर विफल हो रहा है क्योंकि वे एक PROJECT_ID (के बाद से नहीं है परियोजना को बचाया नहीं गया है)।

यह रेल की तरह लगता है नीचे पैटर्न पीछा कर रहा है:

  • मान्य परियोजना
  • मान्य कार्य
  • सहेजें परियोजना
  • सहेजें कार्य

पैटर्न होना चाहिए:

  • मान्य परियोजना
  • दर्रे पर: परियोजना सहेजें और आगे बढ़ें ...
  • मान्य कार्य
    • दर्रे पर: कार्य सहेजें
    • विफल पर: परियोजना को हटाएँ (शायद रोलबैक?)

तो मेरा प्रश्न नीचे उबलता है: मैं माता-पिता के बाद project_id = (या project =) विधि और सत्यापन (बच्चों) पर सत्यापन चलाने के लिए रेल कैसे प्राप्त कर सकता हूं (प्रोजेक्ट) सहेजा गया है, लेकिन अगर कोई बच्चा (कार्य) अमान्य है तो माता-पिता (प्रोजेक्ट) मॉडल को सहेज नहीं सकता है?

कोई विचार?

उत्तर

12

उपयोग रेल 2 के लिए इस सवाल का जवाब है, अन्यथा :inverse_of जवाब

आप इस चारों ओर से PROJECT_ID के लिए जाँच करता है, तो जुड़े परियोजना मान्य है नहीं काम कर सकते हैं के लिए नीचे देखें।


class Task < ActiveRecord::Base 
    belongs_to :project 

    validates_presence_of :project_id, :unless => lambda {|task| task.project.try(:valid?)} 
    validates_associated :project 
end 
+0

यह मेरे लिए काम नहीं किया। Validates_presence_of में: project_id कॉलिंग 'प्रोजेक्ट' शून्य पर वापस आ रहा है जिससे इसे project_id को आजमाया जा सकता है और सत्यापन को विफल कर दिया जा सकता है। मैंने एक और सवाल बनाया क्योंकि मैंने सोचा था कि मुद्दा अलग था लेकिन ऐसा लगता है कि यह वही है http://stackoverflow.com/questions/2102724/rails-nested-attributes-association- validation-failing। –

+10

नीचे उल्टा उलटा समाधान रेल 3.0 और उच्चतर के लिए अधिक सही है। – nertzy

1

तुम बस परियोजना बना सकते हैं और अगर यह मान्यता गुजरता केवल परियोजनाओं जोड़ें:

tasks = params.delete(:task_attributes) 
if Project.create(params) 
    Project.update_attributes(:task_attributes => tasks) 
end 

Ciao

0

विपरीत करने के लिए क्या बिगो पता चलता है, यह पहली बार और फिर पैरेंट ऑब्जेक्ट को बचाने के लिए स्वीकार्य हमेशा नहीं है बच्चे। आम तौर पर आप यह सुनिश्चित करना चाहते हैं कि सभी ऑब्जेक्ट्स उन्हें सहेजने से पहले मान्य करें। इससे उपयोगकर्ता को इनपुट फॉर्म को फिर से संपादित करने और किसी भी त्रुटि को सही करने का मौका मिलता है।

आपके द्वारा वर्णित समस्या रेल 3.0 में तय की जाएगी। मैंने लाइटहाउस टिकट के लिए एक लिंक पोस्ट किया होगा, लेकिन stackoverflow.com इसकी अनुमति नहीं देता है क्योंकि मैं एक नया उपयोगकर्ता (#fail) हूं। लेकिन समय के लिए, आप "parental_control" प्लगइन का उपयोग कर सकते हैं, जो आपके "बग" को ठीक करेगा।

2

दुर्भाग्यवश उपर्युक्त सुझाव रेलवे 2.3.5 के साथ मेरे लिए कोई भी काम नहीं करते हैं।

मेरे मामले में, किसी कार्य में प्रोजेक्ट हमेशा शून्य होता है यदि दोनों नेस्टेड विशेषताओं का उपयोग करके बनाए जाते हैं। केवल अगर मैं validates_presence_of को हटा देता हूं, तो निर्माण सफलतापूर्वक हो जाता है। इकाई परीक्षण और लॉग शो कि सभी सही ढंग से बनाया गया है।

तो अब मैं रेल के बजाय डीबी में बाधाओं को जोड़ता हूं क्योंकि यह पहली जगह में अधिक विश्वसनीय लगता है।

8

केवल रिश्ते को मान्य, नहीं ID:

class Task < ActiveRecord::Base 
    belongs_to :project 

    validates_presence_of :project 
end 

जैसे ही संघ से भर जाता है, ActiveRecord पर विचार करेगी सत्यापन सफल रहा है करने के लिए, या नहीं, मॉडल सहेजा गया है।

class Task < ActiveRecord::Base 
    belongs_to :project, :autosave => true 

    validates_presence_of :project 
end 
+0

आखिर में वह जवाब जो मैं ढूंढ रहा था। – doug

159

उपयोग :inverse_of और validates_presence_of :parent: आप स्वत: सहेजने में जांच करने के लिए और साथ ही, यह सुनिश्चित करने के कार्य की परियोजना हमेशा सहेजा जाता है चाहते हो सकता है। यह आपकी सत्यापन समस्या को ठीक करना चाहिए।

class Dungeon < ActiveRecord::Base 
    has_many :traps, :inverse_of => :dungeon 
    end 

    class Trap < ActiveRecord::Base 
    belongs_to :dungeon, :inverse_of => :traps 
    validates_presence_of :dungeon 
    end 

http://apidock.com/rails/ActiveModel/Validations/HelperMethods/validates_presence_of

https://github.com/rails/rails/blob/73f2d37505025a446bb5314a090f412d0fceb8ca/activerecord/test/cases/nested_attributes_test.rb

+3

रेल 3.0 पर मेरे लिए काम किया –

+1

बहुत बहुत धन्यवाद! यह खूबसूरती से काम करता है, और मैंने कहीं और इसका उल्लेख नहीं देखा है। – Emily

+0

रेल 3.2.3 के लिए अपरिभाषित विधि 'validate_presence_of '। लाइन validates_presence_of होना चाहिए: कालकोठरी। – simeonwillbanks

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