2012-09-24 11 views
6

प्रासंगिक कोड: http://pastebin.com/EnLJUJ8Gरेल 3: क्या मुझे किसी ऑब्जेक्ट को बाद में कॉलबैक में सहेजना चाहिए?

class Task < ActiveRecord::Base 
    after_create :check_room_schedule 

    ... 

    scope :for_date, lambda { |date| where(day: date) } 
    scope :for_room, lambda { |room| where(room: room) } 

    scope :room_stats, lambda { |room| where(room: room) } 
    scope :gear_stats, lambda { |gear| where(gear: gear) } 

    def check_room_schedule 
    @tasks = Task.for_date(self.day).for_room(self.room).list_in_asc_order 
    @self_position = @tasks.index(self) 

    if @tasks.length <= 2 
     if @self_position == 0 
     self.notes = "There is another meeting in 
    this room beginning at # {@tasks[1].begin.strftime("%I:%M%P")}." 
     self.save 
     end 
    end 
    end 

    private 

    def self.list_in_asc_order 
     order('begin asc') 
    end 
end 

मैं एक छोटे से काम अनुप्रयोग बना रहा हूं। प्रत्येक कार्य एक कमरे में सौंपा गया है। एक बार जब मैं कोई कार्य जोड़ता हूं, तो मैं यह देखने के लिए कॉलबैक का उपयोग करना चाहता हूं कि यह देखने के लिए कि पहले और बाद में उसी कमरे में कार्य हैं या नहीं, मैंने अभी जोड़ा है (हालांकि मेरा कोड केवल एक किनारे का मामला संभालता है)।

इसलिए मैंने after_create का उपयोग करने का निर्णय लिया (चूंकि उपयोगकर्ता इसे संपादित करने के लिए मैन्युअल रूप से जांच करेगा, इसलिए बाद में नहीं) इसलिए मैं दिन में कार्यों, दिन में कार्यों को पूछने के लिए दो स्कॉप्स और क्लास विधि का उपयोग कर सकता हूं, और समय के साथ उन्हें आदेश। मैं फिर सरणी में ऑब्जेक्ट पाता हूं और अगर कथन का उपयोग शुरू करता हूं।

मुझे वस्तु को स्पष्ट रूप से सहेजना है। यह काम करता हैं। लेकिन यह अजीब लगता है कि मैं यह कर रहा हूँ। मैं बहुत अनुभवी नहीं हूं (पहला ऐप), इसलिए मुझे यकीन नहीं है कि यह भयानक है या यदि यह सम्मेलन है। मैंने एक गुच्छा खोजा है और एक संदर्भ पुस्तक के माध्यम से देखा है, लेकिन मुझे यह विशिष्ट कुछ भी नहीं देखा है।

धन्यवाद।

उत्तर

3

यह मेरे लिए before_create के लिए एक कार्य जैसा दिखता है। अगर आपको अपने after_* कॉलबैक में सहेजना है, तो संभवतः आप before_* कॉलबैक का उपयोग करना चाहते थे।

before_create में आपको save पर कॉल करने की आवश्यकता नहीं होगी, क्योंकि कॉलबैक कोड आपके लिए चलने के बाद सहेजता है।

और फिर सहेजने के बजाय यह पूछने के लिए कि क्या आपको 2 या अधिक ऑब्जेक्ट रिटर्न मिलते हैं, तो आपको एक ऑब्जेक्ट के लिए पूछताछ करनी चाहिए जो सहेजने से पहले संघर्ष करेगी।

छद्म कोड में, तुम अब क्या है:

after creation 
    now that I'm saved, find all tasks in my room and at my time 
    did I find more than one? 
    Am I the first one? 
     yes: add note about another task, then save again 
     no: everything is fine, no need to re-save any edits 

तुम क्या करना चाहिए था: अधिक इस तरह

before creation 
    is there at least 1 task in this room at the same time? 
    yes: add note about another task 
    no: everything is fine, allow saving without modification 

कुछ:

before_create :check_room_schedule 
def check_room_schedule 
    conflicting_task = Task.for_date(self.day) 
         .for_room(self.room) 
         .where(begin: self.begin) # unsure what logic you need here... 
         .first 
    if conflicting_task 
    self.notes = 
     "There is another meeting in this room beginning at #{conflicting_task.begin.strftime("%I:%M%P")}." 
    end 
end 
+0

के बाद से स्कोप लोड नहीं होगा यह ऑब्जेक्ट (या क्या मैं इसके बारे में गलत हूं?), मुझे इस ऑब्जेक्ट को मैन्युअल रूप से @ टास्क सरणी में डालना होगा, सही? – douglas

+0

मेरा संपादन देखें। मूल रूप से सहेजने से पहले 1 विवाद की जांच करें, यह देखने के बजाय कि आपकी क्वेरी सहेजने के बाद 2 या अधिक ऑब्जेक्ट लौटाती है या नहीं। –

+0

डेटाबेस में रिकॉर्ड के लिए जांच कर रहा है ActiveRecord खोजक विधि 'मौजूद है?' का उपयोग किया जाना चाहिए। [सक्रिय रिकॉर्ड एपीआई डॉक] देखें (http://apidock.com/rails/ActiveRecord/FinderMethods/exists%3F) – unnu

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