2014-04-15 5 views
7

रेल के लिए रूबी का उपयोग करके असीमित मनमानी गुण (कुंजी/मान जोड़े), मेरे पास एक ग्राहक तालिका है जिसे मैं असीमित गुण (कुंजी मान जोड़े) जोड़ने में सक्षम होना चाहता हूं। मुझे यकीन नहीं है कि कुंजी/मूल्य जोड़े अभी तक क्या होंगे, इसलिए मुझे यकीन नहीं है कि यह कैसे करें। उदाहरण के लिए, एक ग्राहक हो सकता है:एक ActiveRecord मॉडल

  • ग्राहक 1 गुण:
    • रंग: 'पीला'
    • ब्रांड: 'नाइके'
    • बिक्री: '33'
  • ग्राहक 2 गुण:
    • रंग: 'लाल'
    • phone_numb एर: '1111111111'
    • खरीद: '2'

असल में, ग्राहकों को एक मुख्य/मान जोड़े में गुण के किसी भी संख्या हो सकती है।

मैं यह कैसे कर सकता हूं?

उत्तर

1

इसके लिए आपको serialize का उपयोग करने में सक्षम होना चाहिए, और अपनी गुणों को अपनी संपत्ति विशेषता में असाइन करना चाहिए, और उन्हें उसी तरह से पुनर्प्राप्त करना चाहिए।

+0

हालांकि, यह उन संपत्तियों से पूछताछ करने के लिए असंभव नहीं है, हालांकि, यह मुश्किल हो जाएगा। –

+0

यह उपयोग किए गए डेटाबेस पर निर्भर करता है। पोस्टग्रेर्स इसे आसानी से समर्थन देता है - http://travisjeffery.com/b/2012/02/using-postgress-hstore-with-rails/ –

+0

हां, अगर आप मणि इंस्टॉल करते हैं। –

10

ऐसा करने का "पारंपरिक" तरीका इकाई-विशेषता-मूल्य, या ईएवी पैटर्न के साथ है। जैसा कि नाम से पता चलता है, आप तीन कॉलम के साथ एक नई तालिका तैयार करेंगे: एक "इकाई" के लिए, जो इस मामले में ग्राहक है, एक "विशेषता" नाम या कुंजी के लिए, और मूल्य के लिए एक है। तो अगर आप इस तरह की एक तालिका होगा:

customer_properties 
+----+-------------+--------------+------------+ 
| id | customer_id | key   | value  | 
+----+-------------+--------------+------------+ 
| 1 |   1 | color  | yellow  | 
| 2 |   1 | brand  | nike  | 
| 3 |   1 | sales  | 33   | 
| 4 |   2 | color  | red  | 
| 5 |   2 | phone_number | 1111111111 | 
| 6 |   2 | purchases | 2   | 
+----+-------------+--------------+------------+ 

आप निश्चित रूप से key पर एक सूचकांक और value (और customer_id पर शायद, निश्चित रूप से करना चाहेंगे, लेकिन रेल करना होगा कि आप के लिए जब आप relation का उपयोग या आपके माइग्रेशन में belongs_to)।

अपने मॉडल में

तब:

# customer.rb 
class Customer < ActiveRecord::Base 
    has_many :customer_properties 
end 

# customer_property.rb 
class CustomerProperty < ActiveRecord::Base 
    belongs_to :customer 
end 

यह इस तरह के उपयोग में सक्षम बनाता है: डेटाबेस डिजाइन चला जाता है

customer = Customer.joins(:customer_properties) 
      .includes(:customer_properties) 
      .where(customer_properties: { key: "brand", value: "nike" }) 
      .first 

customer.customer_properties.each_with_object({}) do |prop, hsh| 
    hsh[prop.key] = prop.val 
end 
# => { "color" => "yellow", 
#  "brand" => "nike", 
#  "sales" => "33" } 

customer.customer_properties.create(key: "email", value: "[email protected]") 
# => #<CustomerProperty id: 7, customer_id: 1, key: "email", ...> 

के रूप में यह बहुत ठोस है, लेकिन जैसा कि आप इसे देख सकते हैं कुछ सीमाएँ हैं: विशेष रूप से , यह बोझिल है। साथ ही, आप एक एकल मान प्रकार तक सीमित हैं (:string/VARCHAR आम है)। यदि आप इस मार्ग पर जाते हैं तो आप संभावित रूप से कम बोझिल गुणों को एक्सेस करने और अपडेट करने के लिए ग्राहक पर कुछ सुविधा विधियों को परिभाषित करना चाहते हैं। मैं अनुमान लगा रहा हूं कि विशेष रूप से एएवी पैटर्न को एक्टिव रिकार्ड के साथ अच्छी तरह से काम करने के लिए रत्न हैं, लेकिन मैं उन्हें अपने सिर के ऊपर से नहीं जानता और मुझे आशा है कि आप मुझे गुगल करने के लिए माफ कर देंगे, क्योंकि मैं मोबाइल हूं।

जैसा कि ब्रैड वेर्थ बताते हैं, अगर आपको केवल मनमानी गुणों को स्टोर करने की आवश्यकता है और उनके द्वारा क्वेरी नहीं है, तो serialize एक शानदार विकल्प है, और यदि आप PostgreSQL का उपयोग करते हैं तो पूछताछ की समस्या भी इसकी महान हिस्टोर सुविधा के लिए धन्यवाद है।

शुभकामनाएं!

+0

ठीक है, आपने मुझे परेशानी बचाई है - ठीक है! –

+0

वाह, महान जवाब (आप भी, ब्रैड)। मैंने serialize इस्तेमाल किया लेकिन यह भी बहुत दिलचस्प है। बहुत बहुत धन्यवाद –

+1

क्या किसी को भी कई रेल मॉडल में इस पैटर्न का उपयोग करने के लिए किसी भी मानक रेल रत्न के बारे में पता है? –

1

आप hydra_attribute gem पर देखना चाहते हैं, जो ActiveRecord मॉडल के लिए एंटीटी-एट्रिब्यूट-वैल्यू (ईएवी) पैटर्न का कार्यान्वयन है।