2013-05-22 12 views
27

मैं सूची प्रबंधन के लिए एक रेल फ्रंटेंस लिख रहा हूं। मैं उन उत्पादों को पंजीकृत करने में सक्षम होना चाहते हैं, तो मेरे पास है:रेल वैकल्पिक वैकल्पिक हैं

class User < ActiveRecord::Base 
    has_many :products 
    # <snip> 
end 

और

class Product < ActiveRecord::Base 
    belongs_to :user 
    # <snip> 
end 

समस्या यह है कि उत्पादों के लिए पहले एक उपयोगकर्ता द्वारा पंजीकृत किया जा रहा बनाई गई हैं है। यही है, Product.create पर कॉल करना पूरी तरह स्वीकार्य है और बस इसे user_id पर nil पर सेट करें। आप कल्पना कर सकते हैं, हालांकि, रेल इस बॉक्स से बाहर का समर्थन नहीं करता:

> Product.create! 
    (0.3ms) SELECT COUNT(*) FROM "products" WHERE "products"."type" IN ('Product') 
    (0.1ms) begin transaction 
    (0.1ms) rollback transaction 
ActiveRecord::RecordInvalid: Validation failed: User can't be blank 
    from ~/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-3.2.13/lib/active_record/validations.rb:56:in `save!' 

मैं kludgey समाधान है, जिनमें से सबसे आकर्षक का एक समूह के बारे में सोचा है एक NullUser उपवर्गीकरण User और उपयोग करने के लिए उत्पादों को बनाने के लिए। लेकिन वह अभी भी एक हैक की तरह लगता है। इसके साथ रेलवे रास्ता क्या है?

धन्यवाद।


प्रासंगिक माइग्रेशन:

class AddUseridToProducts < ActiveRecord::Migration 
    def change 
    add_column :products, :user_id, :integer 
    end 
end 

और बाद में:

class Changeuseridtobeoptionalforproducts < ActiveRecord::Migration 
    def change 
    change_column :products, :user_id, :integer, null: true 
    end 
end 
+0

कृपया, 'उत्पाद' मॉडल पर आपके सभी सत्यापन पोस्ट करें। –

उत्तर

4

क्या आपके पास एक सत्यापन है जिसके लिए उपयोगकर्ता उपस्थित होना आवश्यक है? यदि ऐसा है, तो इसे हटा दें।

belongs_to :user, optional: true 

रेल 5 में, जब भी हम एक belongs_to संघ परिभाषित करते हैं, यह करने के लिए आवश्यक है:

3

रेल बिल्कुल बॉक्स से बाहर इस का समर्थन करता है, अपने विस्थापित जाँच, आप एक बाधा के रूप में :null => false शामिल पर है user_id लाइन? यदि हां, तो इसे बाहर निकालो!

संपादित करें: या @Rodrigo Dias के रूप में, इसे :null => true पर उलट दें।

इसके अलावा, जांचें कि आपके पास उत्पाद मॉडल में उपयोगकर्ता संबंध पर कोई सत्यापन नहीं है।

+1

या बस इस पर स्विच करें: null => true –

+0

मैंने ओपी में अपना माइग्रेशन जोड़ा (लाइन ब्रेक की मृत्यु हो जाने के बाद इसे यहां पेस्ट नहीं किया था)। – tsm

+0

मैंने 'change_column: उत्पादों,: user_id,: integer, null: true' के साथ माइग्रेशन किया है, लेकिन ऐसा कुछ नहीं हुआ। – tsm

108

बस रेल 5 के लिए एक अद्यतन, तो आप इस तरह का व्यवहार चाहते हैं, तो आप इस विकल्प को पारित करने के लिए की आवश्यकता होगी डिफ़ॉल्ट रूप से संबंधित रिकॉर्ड मौजूद है।

+1

उघह ... हम सभी को रिलीज नोट्स पढ़ना चाहिए ... सही ? –

+0

मैंने रेल 5 में यह कोशिश की, मैं इसे वैकल्पिक देखता हूं, लेकिन समस्या यह है कि यदि मैं विदेशी कुंजी फ़ील्ड में एक गैर-मौजूदा मान दर्ज करता हूं, तो यह इसे स्वीकार करता है। इस मामले में यह त्रुटि उत्पन्न करनी चाहिए कि यह प्राथमिक तालिका में उपलब्ध नहीं है। तो इसे कैसे ठीक करें? –

+0

आप वास्तव में किसी भी संबंध के साथ ऐसा कर सकते हैं, मेरा मानना ​​है कि जो भी आप डालते हैं, उस पर एक to_i करने का प्रयास करेंगे, अगर यह संख्या या शून्य नहीं है। आपको उपलब्ध विधियों का उपयोग करना चाहिए जो प्रदान करने के लिए हैं, इस विधि के माध्यम से एसोसिएशन बनाने से गलत मानों को रोक दिया जाएगा, एसोसिएशन.users.build और उपयोगकर्ता का उपयोग करें।गैर-मौजूदा रिकॉर्ड से बचने के लिए build_association, मेरे मामले में, जहां मैं वैकल्पिक सत्य का उपयोग कर रहा हूं, संबंधित उपयोगकर्ता के लिए एक निश्चित रिकॉर्ड के लिए है, यह रिकॉर्ड अतिथि उपयोगकर्ताओं को स्वीकार करता है, इसलिए मैं सिर्फ एसोसिएशन.यूसर = current_user कर रहा हूं, अगर current_user शून्य है मुझे कोई त्रुटि नहीं मिलेगी – Alexis

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