2014-10-28 5 views
5

वहाँ किसी भी तरह से स्वचालित रूप से वस्तु को सहेजते समय बताए संग्रह विशेषताओं (collection_singular_ids = आईडी विधि) से बचने के लिए है?रेल 3 persited वस्तु के लिए मान्यता प्रदर्शन नहीं कर सकते जब उपयोग collection_singular_ids = आईडी विधि

उदाहरण के लिए, मैं अगले टेस्ट और पैकेज मॉडल, पैकेज कई परीक्षण है की है। उपयोगकर्ता परीक्षण संख्या के साथ पैकेज बंडल का निर्माण कर सकते हैं।

कोई मुद्दा सत्यापन पर जब पैकेज वस्तु नई है।

1.9.2 :001> package = Package.new(:name => "sample", :cost => 3.3, :test_ids => [1,2,3,4]) 
=> #<Package id: nil, name: "sample", cost: 3.3> 
1.9.2 :002> package.test_ids 
=> [1, 2, 3, 4] 
1.9.2 :003> package.save 
=> false 
1.9.2 :004> package.save! 
ActiveRecord::RecordInvalid: Validation failed: This package should have at most three tests 
1.9.2: 005> package.test_ids = [1,2] 
=> [1, 2] 
1.9.2 :005> package.save! 
=> true 

लेकिन मैं विधि at_most_3_tests हिट नहीं कर सका कायम पैकेज वस्तु के साथ।

तालिका रिकॉर्ड में शामिल हों पैकेज रूप में कई परीक्षण के चयन के लिए जब परीक्षण आईडी

1.9.2: 006> package 
=> #<Package id: 1, name: "sample", cost: 3.3> 
1.9.2: 007> package.test_ids 
=> [1,2] 
1.9.2: 007> package.test_ids = [1,2,3,4,5] 
=> [1,2,3,4,5] 
1.9.2: 008> package.test_ids 
=> [1,2,3,4,5] 

ग्राहक आवश्यकता बताए तुरंत बनाई गई है ड्रॉप-डाउन इंटरफ़ेस है और यह भी ड्रॉप-डाउन के लिए select2 jQuery प्लगइन का इस्तेमाल किया। Rhmtl कोड लग रहा है

तरह
<%= form_for @package do |f| %> 
    <%= f.text_field :name %> 
    <div> <label>Select Tests</label> </div> 
    <div> 
    <%= f.select "test_ids", options_for_select(@tests, f.object.test_ids), {}, { "data-validate" => true, :multiple => true} %> 
    </div> 

मेरी मदद कृपया इस समस्या को हल करने के लिए।

उत्तर

5

संघों की संख्या सीमित करें के लिए

आप के रूप में निम्नलिखित सत्यापन का उपयोग कर सकते अपनी पद्धति के बजाय निम्नलिखित:

has_many :tests, :length => { :maximum => 3 } 

एकाधिक का उपयोग कर के लिए चयन

मैं यह समस्या है

: से पहले, और मैं इसे निम्नलिखित कोड का उपयोग कर हल 0
<%= f.select(:test_ids, options_from_collection_for_select(@tests, :id, :name, @promotion.test_ids), {}, {multiple: true, "data-validate" => true}) => 

मुझे लगता है कि options_from_collection_for_select, इस link से पोस्ट उदाहरण की श्रेणियां पढ़ें आपकी मदद कर सकती हैं।

मान्यता लिए

मैं validates_associated इस्तेमाल किया, निम्नलिखित के रूप में:

validates_associated :tests 

के रूप में सक्रिय रिकॉर्ड के लिए बनी वस्तु

reload

आप उपयोग कर सकते हैं के लिए पुराने गुण प्राप्त करने के लिए निम्नलिखित:

1.9.2: 006> package 
=> #<Package id: 1, name: "sample", cost: 3.3> 
1.9.2: 007> package.test_ids 
=> [1,2] 
1.9.2: 007> package.test_ids = [1,2,3,4,5] 
=> [1,2,3,4,5] 
1.9.2: 007> package.reload 
=> #<Package id: 1, name: "sample", cost: 3.3> 
1.9.2: 008> package.test_ids 
=> [1,2] 

या आप पैकेज वस्तु के सत्यापन की जांच कर सकते हैं, अगर यह गलत पुनः लोड है:

unless package.valid? 
    package.reload 
end 
+0

मैं पैकेज.डालिद को कॉल करने में सक्षम नहीं हूं? क्योंकि जब भी आईडी की सरणी निर्दिष्ट होती है तो स्वचालित रूप से कार्रवाई को सक्रिय किया जाता है। परीक्षण,: लंबाई => उदाहरण package.test_ids = [1,2,3,4,5] –

+0

@ManivannanJeganathan मैं इस मान्यता 'has_many उपयोग करने के लिए मेरा उत्तर अद्यतन के लिए {: अधिकतम => 3}' –

+0

मेरी मान्यता नहीं है केवल लंबाई पर आधारित है। मैंने अभी उदाहरण कोड दिया है। पैराम्स [: पैकेज] में हमेशा test_ids पैरामीटर होना चाहिए जैसे {: cost => 3.4,: test_ids => [1,2,3,4,5]}। बस मुझे पैकेज मॉडल में सत्यापन विधि को हिट करने की आवश्यकता है और सत्यापन विफल होने पर फ़ॉर्म प्रस्तुत करना होगा। मैं पैकेजटेस्ट मॉडल में '' 'validates_associated: package''' को कॉल करके अपने उत्तर की सहायता से सत्यापन विधि को हिट कर सकता हूं। लेकिन अगर प्रमाणीकरण test_ids सत्यापन से संबंधित विफल रहता है, तो सत्य या गलत लौटने के बजाय अपवाद उठाया जाता है। पूर्व कोड '' 'अगर @ package.update_attributes पैरामीटर [: पैकेज]:' 'के बजाय' '' PackageTest''' में package''' 'किसी और प्रस्तुत करना" फार्म "' '' –

3

आप मैन्युअल रूप से नियंत्रक में test_ids बताए रहे हैं, मैं नेस्टेड विशेषताओं के साथ संपूर्ण वस्तु को अद्यतन करने के सुझाव देंगे बजाय।यह मानता है कि params[:package][:test_ids] आपकी टेस्ट आईडी की सूची में सेट है (जिसे मोहम्मद का उत्तर मदद करेगा)। तो अपने नियंत्रक कार्रवाई कुछ इस तरह दिखेगा:

def update 
    package = Package.find(params[:id]) 
    package.update_attributes params[:package] 
end 

यह एक ActiveRecord/डेटाबेस लेनदेन में बार में सब कुछ अद्यतन करेगा। इसका मतलब है कि यदि सत्यापन विफल रहता है, तो सभी परिवर्तन वापस लुढ़काए जाएंगे, इसलिए इससे कोई फर्क नहीं पड़ता कि परीक्षण सहेजे गए हैं। अधिक जानकारी here है।

इसके अलावा, मैं के बजाय tests.size पर कॉल करने की अनुशंसा करता हूं, क्योंकि प्रतिस्थापन एक बेहतर क्वेरी उत्पन्न करने के लिए प्रवृत्त होगा (या डेटाबेस पर जाना नहीं है)।

+0

ठीक है.पर समस्या है जब test_ids पैरामीटर, साथ update_attributes यह अपवाद बढ़ा देंगे बुला के बजाय सही या गलत लौटने यदि सत्यापन test_ids सत्यापन (at_most_3_tests विधि) से संबंधित विफल रहता है। कोई उपाय? उदाहरण कोड: package.update_attributes पैरामीटर अगर [: पैकेज] –

+0

मैं इस्तेमाल किया ** validates_associated: PackageTest मॉडल –

+0

validates_associated डिफ़ॉल्ट रूप से एक अपवाद बढ़ा नहीं करना चाहिए में पैकेज **। आप क्या त्रुटि प्राप्त कर रहे हैं? – Ari

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