2012-03-15 15 views
9

बचाने वस्तुओं।रूबी ऑन रेल्स संघ के माध्यम से has_many इससे पहले कि मैं संघ एक ActiveRecord पर वस्तुओं का उपयोग करने के डेटाबेस के लिए सब कुछ बचत करने से पहले कोशिश कर रहा हूँ एक रूबी ऑन रेल्स परियोजना पर

class Purchase < ActiveRecord::Base 

    has_many :purchase_items, dependent: :destroy 
    has_many :items, through: :purchase_items 

    validate :item_validation 

    def item_ids=(ids) 
    ids.each do |item_id| 
     purchase_items.build(item_id: item_id) 
    end 
    end 

    private 

    def item_validation 
    items.each do |item| 
     ## Lookup something with the item 
     if item.check_something 
     errors.add :base, "Error message" 
     end 
    end 
    end 

end 

अगर मैं ऐसा तरह मेरे वस्तु बाहर का निर्माण: purchase = Purchase.new(item_ids: [1, 2, 3]) और यह item_validation विधि को बचाने के लिए आइटम संग्रह अब तक तैयार नहीं है की कोशिश है, तो भले ही आइटम की स्थापना की गई निर्धारित किया है कि यह एक नहीं मिलता है उनमें से किसी पर check_something विधि को कॉल करने का मौका।

यह मेरी खरीद मॉडल और संघ मॉडल से पहले आइटम संग्रह तक पहुँचने के लिए कायम कर रहे हैं ताकि मैं उनके खिलाफ सत्यापन चला सकते हैं संभव है?

अगर मैं अपने item_validation पद्धति को बदलने के लिए:

def item_validation 
    purchase_items.each do |purchase_item| 
    item = purchase_item.item 
    ## Lookup something with the item 
    if item.something 
     errors.add :base, "Error message" 
    end 
    end 
end 

यह तरह से मैं यह करना चाहते हैं काम करने के लिए लगता है, लेकिन मैं इस पर विश्वास करना मुश्किल सीधे के साथ आइटम संग्रह तक पहुँचने के लिए कोई रास्ता नहीं है कि वहाँ लगता है मेरी खरीद से पहले रेल और संबंधित रिकॉर्ड डेटाबेस में सहेजे जा रहे हैं।

उत्तर

0

आप प्रलेखन कि इंगित करता है purchase = Purchase.new(item_ids: [1, 2, 3]) आप क्या उम्मीद कर रहे हैं करता है?

मेरे जैसा दिखता है कि मैं सिर्फ एक डेटाबेस में गैर-डेटाबेस विशेषता 'item_ids' सेट कर रहा हूं (यानी एक एसोसिएशन नहीं बना रहा)।

आपकी खरीद मॉडल भी नहीं सीधे सेट करने के लिए किसी भी विदेशी कुंजी कॉलम होना चाहिए। इसके बजाय purchase_items तालिका में प्रविष्टियां हैं जिनमें purchase_id और item_id है। अपनी खरीद और तीन आइटमों के बीच एक लिंक बनाने के लिए आपको जॉइनर टेबल में तीन प्रविष्टियां बनाने की आवश्यकता है।

अगर आप सिर्फ बजाय ?:

purchase = Purchase.new 
purchase.items = Item.find([1,2,3]) 
1

inverse_of तर्क जोड़ने के लिए प्रयास करें: has_many में और परिभाषाओं belongs_to। inverse_of तर्क यह अन्य मॉडल पर रिश्ते का नाम है उदाहरण के लिए,:

class Post < ActiveRecord::Base 
    has_many :comments, inverse_of: :post 
end 

class Comment < ActiveRecord::Base 
    belongs_to :post, inverse_of: :comments 
end 

ऐसे PurchaseItem और आइटम के रूप में अन्य वर्गों,

आशा पर भी इसे जोड़ने के लिए मत भूलना यह

में मदद करता है
1

अपनी खुद की item_ids= विधि हटाएं - रेल आपके लिए एक उत्पन्न करती है (collection_singular_ids=ids देखें)। यह आपकी समस्या को पहले ही हल कर सकता है।

class Purchase < ActiveRecord::Base 

    has_many :purchase_items, dependent: :destroy 
    has_many :items, through: :purchase_items 

    validate :item_validation 

    private 

    def item_validation 
    items.each do |item| 
     ## Lookup something with the item 
     if item.check_something 
     errors.add :base, "Error message" 
     end 
    end 
    end 

end 

दूसरी बात यह है कि मेरे मन में आता है अपने कोड को देख: Item वर्ग के लिए मान्यता ले जाएँ। तो:

class Purchase < ActiveRecord::Base 
    has_many :purchase_items, dependent: :destroy 
    has_many :items, through: :purchase_items 
end 

class Item < ActiveRecord::Base 
    has_many :purchase_items 
    has_many :purchases, through: :purchase_items 

    validate :item_validation 

    private 

    def item_validation 
     if check_something 
     errors.add :base, "Error message" 
     end 
    end 
end 

आपका Purchase रिकॉर्ड भी अवैध हो सकता है अगर Item रों में से एक अमान्य है।

0

मुझे लगता है कि आप उन्हें एक्सेस नहीं कर सकते हैं क्योंकि Purchase रिकॉर्ड से पहले उपलब्ध नहीं है। लेकिन जैसा कि आप का उल्लेख आप पहले स्तर संघ purchase_items के लिए उपयोग किया है, तो आप सब आईडी निकालने और Item के लिए where में उन्हें पारित कर सकते हैं:

items = Item.where(purchase_item_id: purchase_items.map(&:id))