2012-02-21 13 views
7

मेरे पास मेरे फॉर्म में 3 फ़ील्ड हैं जो मेरे डेटाबेस में नहीं हैं: opening_type, opening_hours, opening_minutes। मैं इन 3 क्षेत्रों के साथ मुख्य विशेषता "खोलने" (डेटाबेस में) को अद्यतन करना चाहता हूं।रेल - मॉडल में नहीं विशेषताएँ और मॉडल विशेषता अद्यतन करें

मैंने बहुत सी चीजों की कोशिश की जो काम नहीं करते हैं।

वास्तव में मेरे पास है:

attr_accessor :opening_type, :opening_hours, :opening_minutes 

    def opening_type=(opening_type) 
    end 
    def opening_type 
    opening_type = opening.split("-")[0] if !opening.blank? 
    end 

    def opening_hours=(opening_hours) 
    end 
    def opening_hours 
    opening_hours = opening.split("-")[1] if !opening.blank? 
    end 

    def opening_minutes=(opening_minutes) 
    end 
    def opening_minutes 
    opening_minutes = opening.split("-")[2] if !opening.blank?  
    end 

मैं की तरह कुछ जोड़ने की कोशिश की:

def opening=(opening) 
    logger.info "WRITE" 

    if !opening_type.blank? and !opening_hours.blank? and opening_minutes.blank? 
     opening = "" 
     opening << opening_type if !opening_type.blank? 
     opening << "-" 
     opening << opening_hours if !opening_hours.blank? 
     opening << "-" 
     opening << opening_minutes if !opening_minutes.blank? 
    end 
    write_attribute(:opening, opening) 
    end 

    def opening 
    read_attribute(:opening) 
    end 

लेकिन, accessors पद्धतियों को बुलाया नहीं कर रहे हैं और मुझे लगता है कि opening_type, OPENING_HOURS, opening_minutes भी खाली थे accessors कहा जाता था ...

मुझे लगता है कि मुझे पहले से बचाए कॉलबैक की आवश्यकता नहीं है और इसे एक्सेसर्स को फिर से लिखना चाहिए।

नोट्स: - रेल 3.0.5, - opening_type,: OPENING_HOURS,: opening_minutes खाली

संपादित किया जा सकता है: मैं अपने कोड

उत्तर

15

ध्यान दें कि attr_reader, attr_writer और attr_accessor सिर्फ अपने स्वयं के तरीकों को परिभाषित करने के लिए मैक्रो।

# attr_reader(:foo) is the same as: 
def foo 
    @foo 
end 

# attr_writer(:foo) is the same as: 
def foo=(new_value) 
    @foo = new_value 
end 

# attr_accessor(:foo) is the same as: 
attr_reader(:foo) 
attr_writer(:foo) 

फिलहाल, अपने सेटर तरीकों कुछ भी विशेष नहीं कर रहे हैं, इसलिए यदि आप सिर्फ attr_accessor करने के लिए स्विच अपने कोड क्लीनर बन जाएगा।

आपकी अन्य समस्या यह है कि आपकी opening= विधि को कभी भी नहीं कहा जा रहा है, और यह समझ में आता है क्योंकि आपके कोड में कहीं भी यह नहीं है। आप जो वास्तव में चाहते हैं वह आपके खोलने के लिए सभी व्यक्तिगत भागों को सेट करने के बाद सेट किया जा सकता है। अब यह करने के लिए कोई तुच्छ तरीका है, लेकिन रेल एक before_validation कॉलबैक जहां कोड मूल्यों को निर्धारित किया गया है के बाद चलता है लेकिन इससे पहले कि मान्यता चलाता है कि डाल सकते है:

class Shop < ActiveRecord::Base 

    attr_accessor :opening_type, :opening_hours, :opening_minutes 

    before_validation :set_opening 

    private 
    def set_opening 
    return unless opening_type && opening_hours && opening_minutes 
    self.opening = opening_type + "-" + opening_hours + "-" + opening_minutes 
    end 
end 
+0

नोट करें यह उत्तर मानता है कि आप केवल डेटाबेस में संयुक्त 'उद्घाटन' फ़ील्ड को स्टोर करना चाहते हैं। एक और दृष्टिकोण डाटाबेस में अलग-अलग घटकों को स्टोर करना और मांग पर गतिशील रूप से संयुक्त स्ट्रिंग बनाना होगा। आपकी आवश्यकताओं के आधार पर जो आपके लिए बेहतर दृष्टिकोण भी हो सकता है। – Gareth

+0

मुझे यह डेटाबेस खोलने वाले क्षेत्र के साथ मिलता है। यह डेटाबेस एक स्मार्टफोन ऐप के साथ सिंक करता है और मैं 3 अलग-अलग क्षेत्रों को स्टोर करने के लिए अपनी संरचना नहीं बदल सकता। ;-) पहले_विधीकरण कॉलबैक के साथ समस्या यह है कि जब आप फॉर्म को संपादित करने जा रहे हैं तो आप मामले को संभाल नहीं सकते ... और जहां मुझे फॉर्म के लिए 3 वर्र्स में उद्घाटन क्षेत्र को छोटा करने की आवश्यकता है। मुझे पता है कि मैं इसे मैन्युअल रूप से कर सकता हूं लेकिन मैंने सोचा कि एक्सेसर्स के साथ ऐसा करने के लिए एक बेहतर तरीका था ... –

+0

सभी सच है, लेकिन 'उद्घाटन =' ओवरराइड करने का आपका सुझाव बहुत सी चीजें तोड़ देगा। साथ ही, यह एक बहुत ही स्केची विचार है जिसमें एक सेटर विधि है जो पूरी तरह से पारित पैरामीटर को त्याग देता है। एक अलग विधि (जैसे कि 'set_opening') के लिए बेहतर है जो यह स्पष्ट करता है कि यह क्या कर रहा है। आपके पास उस विधि को कॉल करने के लिए पहले_अधिकृतता का उपयोग करने के लिए * नहीं है लेकिन मैं गंभीरता से अनुशंसा करता हूं कि यह एक अलग विधि है – Gareth

0

बजाय

attr_reader :opening_type, :opening_hours, :opening_minutes 

आप की जरूरत अद्यतन

attr_accessor :opening_type, :opening_hours, :opening_minutes 
attr_reader :opening_type, :opening_hours, :opening_minutes 

एचएफ ...

// हैं: opening_type,: opening_hours,: open_minutes वास्तविक फ़ील्ड? यदि हां तो आपको बस इसकी आवश्यकता है?

attr_accessor: उद्घाटन attr_reader: उद्घाटन

+0

ठीक है, मैं attr_accessor के लिए बदल दिया है। लेकिन शुरुआती एक्सेसर्स को नहीं कहा जाता है ... –

+0

अद्यतन देखें, .... – davidb

+0

नहीं। वास्तविक क्षेत्र मेरे डेटाबेस में "खोलना" है। मुझे अपने फॉर्म से भेजे गए 3 फ़ील्ड को सम्मिलित करने की आवश्यकता है: main_type, opening_hours, opening_minuts मुख्य "खोलने" फ़ील्ड को भरने के लिए। ये 3 फ़ील्ड डेटाबेस में नहीं हैं। मैंने पहली पोस्ट अपडेट की। –

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