obo*_*obo 8 ruby rspec ruby-on-rails mongoid observer-pattern
在一个简单的mongoid数据模型上,用户有很多评论,我想在用户写至少一条评论时给用户一个特定的徽章.所以我建立了一个像这样的观察者:
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
Run Code Online (Sandbox Code Playgroud)
user.award方法:
def award(badge)
self.badges << badge
self.save
end
Run Code Online (Sandbox Code Playgroud)
以下测试失败(但我想这是正常的,因为观察者在后台执行?)
it 'should award the user with comment badge' do
@comment = Factory(:comment, :user => @user)
@user.badges.count.should == 1
@user.badges[0].title.should == "Comment badge"
end
Run Code Online (Sandbox Code Playgroud)
什么是验证此行为的最佳方法?
我有一个独立的代码改编(见下文).我不得不做三个小改动,让它按照你期望的方式工作.
要使Observer正常工作,您必须实例化它.在我的例子中,我需要添加以下行:
Mongoid.observers = CommentBadgeObserver
Mongoid.instantiate_observers
Run Code Online (Sandbox Code Playgroud)
在Rails中你可以实现相同的功能,将它添加到config/application.rb(根据文档):
config.mongoid.observers = :comment_badge_observer
Run Code Online (Sandbox Code Playgroud)
我觉得还有一个小逻辑错误的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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1164 次 |
最近记录: |