2012-10-11 17 views
7
में विरासत

मैं वर्तमान में DBIx साथ इस परिदृश्य पर लागू करने के लिए कोशिश कर रहा हूँ:DBIx और पर्ल

package Product; 
use base 'DBIx::Class::Core'; 
__PACKAGE__->table("products"); 
__PACKAGE__->add_columns(
    "productId", 
    { data_type => "varchar", is_nullable => 0, size => 10}, 
    "name", 
    { data_type => "varchar", is_nullable => 1, size => 150}, 
    "type", 
    { 
    data_type => "enum", 
    default_value => "general", 
    extra => { 
     list => ["general", "bundle"], 
    }, 
    is_nullable => 0, 
    }); 

आप देख सकते हैं, मौसम उत्पाद एक सामान्य उत्पाद है या एक बंडल उत्पाद स्तंभ प्रकार में सहेजा गया है।

अब मैं वर्ग की पहचान में यह जानकारी संपुटित चाहते हैं:

  • उत्पाद (type कोई फर्क नहीं पड़ता)
  • BundleProduct (type = 'बंडल')
  • : मैं निम्नलिखित वर्गों करना चाहते हैं
  • GeneralProduct (type = 'सामान्य')

मैं ने लिखा है:

012,
package BundleProduct; 
use base 'Product'; 

__PACKAGE__->resultset_attributes({ where => { 'type' => 'bundle' } }); 
1; 

और

package GeneralProduct; 
use base 'Product'; 

__PACKAGE__->resultset_attributes({ where => { 'type' => 'general' } }); 
1; 

लेकिन जब

my @allProducts = $schema->resultset('BundleProduct')->all; 

क्रियान्वित सभी सामान्य उत्पादों लाई जाती हैं। यद्यपि परिणामस्वरूप ऑब्जेक्ट्स उदाहरण हैं BundleProduct, जेनरेट किए गए एसक्यूएल में GeneralProduct (type = 'सामान्य' वर्ग की WHERE-condition शामिल है। इससे भी बदतर: यदि मैं Product (BundleProduct और GeneralProduct की आधार श्रेणी) लाने की कोशिश करता हूं तो स्थिति type = 'सामान्य' भी लागू होती है! ऐसा लगता है कि GeneralProduct के भीतर परिभाषा अन्य सभी परिभाषाओं को ओवरराइट करती है।

मेरे डिजाइन में क्या गलत है?

उत्तर

0

यह हमेशा सामान्य पर डिफ़ॉल्ट हो सकता है क्योंकि डेटा को एनम ऑब्जेक्ट में नहीं बढ़ाया जा रहा है?

आश्चर्य है कि यह एक स्पष्ट त्रुटि नहीं देता है, लेकिन शायद (Product पैकेज के लिए) नीचे जोड़ने आपकी समस्या का समाधान होगा:

__PACKAGE__->load_components(qw/InflateColumn::Object::Enum/); 

अतिरिक्त ऊपर करने के लिए भी अपने प्रकार स्तंभ परिभाषा को is_enum => 1 जोड़ने का प्रयास करें:

type => { 
    data_type  => "enum", 
    is_enum  => 1, 
    default_value => "general", 
    is_nullable => 0, 
    extra => { 
    list => ["general", "bundle"], 
    }, 
}, 

एनबी। इससे मुद्रास्फीति वस्तु() के उपयोग को लागू करना चाहिए, जबकि इसके बिना मेरा मानना ​​है कि यह enum का उपयोग करने वाले आरडीबीएमएस के मूल निवासी (यदि इसका वर्तमान है) का उपयोग करने का प्रयास करता है।

फिंगर्स ने इस काम को पार किया।यदि यह देखने के लिए default_value को हटाने का प्रयास न करें यह कैसे चीजों को प्रभावित करता है।

+0

@dreagtun धन्यवाद, लेकिन मुझे लगता है कि InflateColumn :: ऑब्जेक्ट :: Enum केवल 'वर्चर' फ़ील्ड को एप्लिकेशन के भीतर 'enum' फ़ील्ड में परिवर्तित करने के लिए नामित किया गया है। [लिंक] (http://search.cpan.org/~jmmills/DBIx-Class-InflateColumn-Object-Enum-0.04/lib/DBIx/Class/InflateColumn/Object/Enum.pm) –

+0

प्रदान किए गए परीक्षणों को देखते हुए 'डीबीआईएक्स :: कक्षा :: इन्फ्लैट कॉलम :: ऑब्जेक्ट :: एनम 'मॉड्यूल द्वारा लेखक हमेशा घटक लोड करता है और' is_enum => 1' भी सेट करता है। यहां परीक्षण है जो आप अपने उदाहरण में जो करने की कोशिश कर रहे हैं उससे मेल खाता है: https://metacpan.org/source/JMMILLS/DBIx-Class-InflateColumn-Object-Enum-0.04/t/lib/TestDB/NativeEnumNoneNullable.pm लेखक हो सकता है कि उत्साही हो लेकिन शायद यह कोशिश करने लायक हो। लेखक भी 'default_value' परीक्षण नहीं प्रदान करता है, इसलिए वहां कोई समस्या हो सकती है? वैसे भी मैंने तदनुसार अपना जवाब अपडेट कर लिया है। – draegtun

0

यह थोड़ा ओटी हो सकता है, लेकिन मुझे लगता है कि मेरे स्कीमा में enum डेटा प्रकारों से निपटने के दौरान हमेशा कुछ कपटपूर्ण अनुप्रयोग कार्यान्वयन समस्या में भाग लेते हैं।

तो मैं अब उनका उपयोग नहीं करता हूं। मैं विदेशी कुंजी रिश्ते और या तो व्यक्तिगत टेबल या एक संयुक्त तालिका सभी कोड पकड़े उपयोग करें:

<id, code_type, code_name> 
< 1, 'product_type', 'bundle'> 
< 2, 'product_type', 'general'> 

और फिर मैं उत्पाद से शामिल होने के product.product_type_id = code_table.id

पर इस तकनीक को आवेदन कार्यान्वयन बना दिया है उत्पाद_प्रकार को परियोजना की शुरुआत में कुछ अतिरिक्त डेटाबेस प्रबंधन की लागत पर बहुत अधिक आसान है।

+1

आप एक उत्पाद के साथ 'product_types' तालिका बनाकर शामिल होने से बच सकते हैं, प्रकार का नाम, जिसमें एक अद्वितीय बाधा है और' उत्पादों 'तालिका में एक विदेशी कुंजी है। विदेशी कुंजी क्षेत्र के लिए मूल्यों के सीमित सेट को लागू करेगी, और चूंकि कुंजी एक संख्या के बजाय नाम है, इसलिए अतिरिक्त जुड़ने की आवश्यकता नहीं है। – friedo

+0

सच है। लेकिन अब मैं चाबियों के लिए डेटा का उपयोग नहीं करता हूं। कोई फर्क नहीं पड़ता कि मैं कितनी मेहनत करता हूं, कोई अंततः मुख्य डेटा बदलना चाहता है और फिर आपके पास उन अपडेटों को पूरा करने के लिए अतिरिक्त काम है। यदि कोड अक्सर उपयोग किया जाता है, तो यह स्मृति में होगा इसलिए शामिल होने में अधिक समय नहीं लगेगा। पृथ्वी पर क्यों सभी शामिल होने से डरते हैं? –

4

resultset_attributes का उपयोग अनुशंसित नहीं है। आप तरीकों bundle_products और general_products साथ Product के लिए एक परिणाम सेट वर्ग को लागू करना चाहिए:

package My::Schema::ResultSet::Product; 
use base 'DBIx::Class::ResultSet'; 

sub bundle_products { shift->search({ type => 'bundle' }); } 
sub general_products { shift->search({ type => 'general' }); } 

तो फिर तुम इस तरह विशिष्ट उत्पादों को खोज सकते हैं:

$schema->resultset('Product')->bundle_products->all; 
$schema->resultset('Product')->general_products->all; 

documentation of resultset_attributes देखें।

DBIx::Class::DynamicSubclass पर भी एक नज़र डालें। जब परिणाम subclassing यह कुछ उपयोगी सुविधाओं को जोड़ता है।

+0

++ डीबीआईएक्स :: कक्षा :: गतिशील Subclass इस परिदृश्य में – tospo

+0

... या इसे "हाथ से" करें जैसा कि कुकबुक में वर्णित है: http://search.cpan.org/~ribasushi/DBIx-Class-0.08250/ lib/DBIx/कक्षा/मैनुअल/Cookbook.pod # Dynamic_Sub-classing_DBIx :: Class_proxy_classes_% 28AKA_multi-class_object_inflation_from_one_table% 29 – tospo

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