2010-09-21 16 views
32

डिफ़ॉल्ट रूप से, ActiveRecord सभी फ़ील्ड को संबंधित डेटाबेस तालिका से लेता है और उन सभी के लिए सार्वजनिक विशेषताओं को बनाता है।क्या Rails ActiveRecord निजी गुण बनाने का कोई तरीका है?

मुझे लगता है कि यह उचित है मॉडल मॉडल में सभी विशेषताओं को बनाने के लिए। इससे भी अधिक, आंतरिक उपयोग के लिए मौजूद विशेषताओं का खुलासा मॉडल के इंटरफ़ेस को रोकता है और encapsulation सिद्धांत का उल्लंघन करता है।

तो, क्या कुछ विशेषताओं को सचमुच private बनाने का कोई तरीका है?

या, शायद मुझे किसी अन्य ओआरएम पर जाना चाहिए?

उत्तर

29

Jordini वहाँ रास्ता

अधिकांश का का सबसे था activ_record method_missing में होता है। आप सामने विधि को परिभाषित करते हैं, तो यह है कि विधि के लिए method_missing मारा नहीं करेगा, और जगह में तुम्हारा का उपयोग करें (प्रभावी रूप से अधिलेखित, लेकिन वास्तव में नहीं)

class YourModel < ActiveRecord::Base 

    private 

    def my_private_attribute 
    self[:my_private_attribute] 
    end 

    def my_private_attribute=(val) 
    write_attribute :my_private_attribute, val 
    end 

end 
+1

कोई कारण नहीं है कि मैं इसे पूरा करने के लिए निम्नलिखित का उपयोग नहीं कर सकता/सकती हूं? निजी attr_accessor my_private_attribute –

+2

@TC: क्योंकि वे वास्तव में विशेषताओं को सही ढंग से ट्रैक नहीं करेंगे। write_attribute/read_attribute विधियां जिस तरह से आप active_record –

+0

के साथ इंटरफ़ेस करते हैं, वास्तव में, write_attribute डीबी के मान को जारी नहीं रखेगा। वास्तव में डीबी में रिकॉर्ड को अपडेट करने के लिए स्वयं को self.save को कॉल करना होगा। – Magne

5
अच्छी तरह से

, आप हमेशा तरीकों रद्द कर सकते थे ...

class YourModel < ActiveRecord::Base 

    private 

    def my_private_attribute 
    self[:my_private_attribute] 
    end 

    def my_private_attribute=(val) 
    self[:my_private_attribute] = val 
    end 

end 
+0

ऐसा लगता है कि यह एक त्रुटि जब मॉडल वर्ग से अद्यतन का उपयोग कर देता है। – NicolasWebDev

1

आप निजी एक मौजूदा विधि बना सकते हैं:

YourClass.send(:private, :your_method) 
+1

यह वास्तव में ActiveRecord के साथ दुर्भाग्य से काम नहीं करता है क्योंकि एक्सेसर विधियों को वास्तव में परिभाषित नहीं किया जाता है, वे method_missing और थोड़ा मेटा प्रोग्रामिंग के साथ बनाए जाते हैं। – brad

6

हाल ही में इस पर ठोकर खाई। यदि आप निजी लेखन और पढ़ने और सार्वजनिक पढ़ने जैसे

class YourModel < ActiveRecord::Base 

    attr_reader :attribute 

    private 

    attr_accessor :attribute 


end 

मेरे लिए ठीक काम करने लगते हैं। आप यह तय करने के लिए attr_reader, attr_writer और attr_accessor के साथ परेशान हो सकते हैं कि क्या खुलासा किया जाना चाहिए और निजी क्या होना चाहिए।

+1

मुझे पूरा यकीन है कि यह नियमित एआर विशेषताओं के साथ काम नहीं करेगा, क्योंकि वे हैं उदाहरण चर में संग्रहीत नहीं है (जो attr_ * विधियों के साथ काम करते हैं)। –

+1

मैंने हर जगह इस जवाब की तलाश की! ऐसा लगता है कि यह काम करता था और वास्तव में जो मैं खोज रहा था। धन्यवाद! – ootoovak

+0

बाहरी मॉडल से मैं 'your_model_instance [: my_private_attribute] =" Foo "' कर सकता हूं और विशेषता मान बदल सकता हूं। बहुत बदसूरत! –

0

सेटिंग निजी बनाना ActiveRecord त्रुटि उत्पन्न करता है।

मैं फोन करने वाले की जाँच करके सार्वजनिक सेटर के ओवरराइट विधि में अभिगम नियंत्रण कोड डाल:

def my_private_attribute=(val) 
    if (caller.first.include?('active_record/base.rb') || caller.first.include?('app/models/myclass.rb')) 
    self[:my_private_attribute] = val 
    else 
    raise Exception.new("Cannot set read-only attribute.") 
    end 
end 
1

मुझे दोनों ओटो और jordinl से विधियों के लिए ठीक काम कर रहा है और पारित करने के लिए कक्षा की वस्तु के लिए rspec कर रहे हैं:

object.should_not respond_to :attribute 

लेकिन जब मैं jordinl विधि का उपयोग करें, मैं एक प्रतिवाद संदेश के लिए नहीं सीधे डेटाबेस के लिए लिखते हैं, लेकिन इसके बजाय attr_writer उपयोग किया है।

अद्यतन:

लेकिन वास्तव में "सही" metod करने के लिए यह पता चला है सरल होने के लिए। Mladen Jablanović और क्रिस्टोफर Creutzig from here के लिए धन्यवाद। पूर्वनिर्धारित विधि निजी या संरक्षित करने के लिए ... बस इसे फिर से परिभाषित:

Class Class_name 

    private :method_name 
    protected :method_name_1 
end 

क्या महत्वपूर्ण है, तो आप पहले से परिभाषित विधि के तर्क को फिर से लिखने की जरूरत नहीं है।

0

मुझे नहीं लगता कि ऐसा करने के लिए 100% विश्वसनीय तरीका है।यह भी गुण का उपयोग करने के सबसे अधिक लोकप्रिय रास्ता जाँच के लायक है:

http://www.davidverhasselt.com/set-attributes-in-activerecord/

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