2011-11-22 12 views
8

के साथ मोंगोइड :: पर्यवेक्षक का परीक्षण कैसे करें, जिसमें एक उपयोगकर्ता के साथ एक साधारण मोंगोइड डेटा मॉडल पर कई टिप्पणियां हैं, मैं कम से कम 1 टिप्पणी लिखते समय उपयोगकर्ता को एक विशिष्ट बैज के साथ पुरस्कार देना चाहता हूं।रियोपेक

class CommentBadgeObserver < Mongoid::Observer 
    observe :comment 

    def after_create(comment) 
    CommentBadge.check_conditions_for(comment.user) 
    end 
end 

class CommentBadge < Badge 
    def self.check_conditions_for(user) 
    if user.comments.size > 1 
     badge = CommentBadge.create(:title => "Comment badge") 
     user.award(badge) 
    end 
    end 
end 

user.award विधि: (? लेकिन मैं यह सामान्य है क्योंकि पर्यवेक्षकों पृष्ठभूमि में क्रियान्वित कर रहे हैं लगता है)

def award(badge) 
    self.badges << badge 
    self.save 
end 

निम्न परीक्षण में विफल रहता है

तो मैं इस तरह एक पर्यवेक्षक की स्थापना

इस व्यवहार को सत्यापित करने का सबसे अच्छा तरीका क्या हो सकता है?

उत्तर

7

मुझे आपके कोड का एकमात्र स्टैंड-अलोन अनुकूलन मिला है (नीचे देखें)। जिस तरह से आप उम्मीद कर रहे थे, उसे काम करने के लिए मुझे तीन छोटे बदलाव करना पड़ा।

ऑब्जर्वर को काम करने के लिए आपको तुरंत इसे चालू करना होगा। (docs के अनुसार)

Mongoid.observers = CommentBadgeObserver 
Mongoid.instantiate_observers 

रेल में आप एक ही बात config/application.rb को यह जोड़ने को प्राप्त कर सकते हैं:: मेरे उदाहरण में मैं लाइनों को जोड़ने के लिए की जरूरत

config.mongoid.observers = :comment_badge_observer 

मैं वहाँ लगता है CommentBadge.check_conditions_for में भी एक छोटी तर्क त्रुटि है, > 1> 0 होना चाहिए।

अंत में मैंने उपयोगकर्ता के बजाए बैज को बचाने के लिए User#award विधि बदल दी, क्योंकि 'विदेशी कुंजी' फ़ील्ड जो रिश्ते को स्टोर करता है बैज पक्ष पर है।

class Comment 
    include Mongoid::Document 
    field :name 
    belongs_to :user 
end 

class CommentBadgeObserver < Mongoid::Observer 
    observe :comment 

    def after_create(comment) 
    CommentBadge.check_conditions_for(comment.user) 
    end 
end 

class Badge 
    include Mongoid::Document 
    field :title 
    belongs_to :user 
end 

class CommentBadge < Badge 
    def self.check_conditions_for(user) 
    if user.comments.size > 0 
     badge = CommentBadge.create!(:title => "Comment badge") 
     user.award(badge) 
    end 
    end 
end 

class User 
    include Mongoid::Document 
    field :first_name 
    has_many :comments 
    has_many :badges 

    def award(badge) 
    self.badges << badge 
    badge.save! 
    end 
end 

Factory.define(:user) do |u| 
    u.first_name 'Bob' 
end 

Factory.define(:comment) do |c| 
    c.name 'Some comment...' 
end 

# Observers need to be instantiated 
Mongoid.observers = CommentBadgeObserver 
Mongoid.instantiate_observers 

describe CommentBadgeObserver do 
    it 'should create badges' do 
    @user = Factory.build(:user) 
    @comment = Factory(:comment, :user => @user) 
    @user.badges.count.should == 1 
    @user.badges[0].title.should == "Comment badge" 
    end 
end 
+0

यह बहुत अच्छा काम करता है! बहुत बहुत धन्यवाद स्टीव! – obo

+0

यह जानना अच्छा है और धन्यवाद। क्या आप इसे अपने रेल में काम कर रहे थे और क्या यह पर्यवेक्षक तत्काल था या कुछ और? – Steve

+0

हाँ, मैंने यह मेरे आवेदन में काम किया है; मुझे अपनी spec फ़ाइल में पर्यवेक्षक तत्काल की दो पंक्तियां सेट करनी पड़ीं। – obo