如何在RoR中实现一个成就系统
我试图在Ruby on Rails应用程序中实现一个成就系统。
我有一长串的成就,我想检查。 所有这些都是由各种控制器中的一些创build操作触发
我有这样的想法,我将有一个成就模式,其中包括控制器和响应的行动。 然后做一个之前的创buildfilter,并检查适用的成就。 当涉及到实际定义/执行成就时,我会陷入困境。 每个成就可能需要不同的数据。 例如,人们会想知道用户已经回答了多less个问题,另外还有多less个评论,以及多less个用户邀请的人回复了他们。
实际上是把所有必要的ruby代码直接embedded到数据库中是最好的办法吗? 我可以看到做一个自包含的块,做所有积极的logging查找等,并返回true / false,虽然我们仍然有一些问题知道什么是提前设置(即current_user等)。
那里有任何合理的最佳做法,不会让我感到肮脏? 我可以看到一个完整的策略/规则引擎是一条path,虽然这可能比计划更吓人。
谢谢! 奥伦
我同意你的想法使用Achievement
模式。
不过,你可能不应该在你的控制器中实现触发器。 想象一下,你有两种方式发表评论; 你将不可避免地得到代码重复。 这种行为属于模型。
假设您想跟踪用户所做评论的数量,并奖励100条评论的成就。 你可以有以下型号:
class User < ActiveRecord::Base has_many :comments has_many :achievements def award(achievement) achievements << achievement.new end def awarded?(achievement) achievements.count(:conditions => { :type => achievement }) > 0 end end class Achievement < ActiveRecord::Base belongs_to :user end class Comment < ActiveRecord::Base belongs_to :user end class CommentAchievement < Achievement def self.check_conditions_for(user) # Check if achievement is already awarded before doing possibly expensive # operations to see if the achievement conditions are met. if !user.awarded?(self) and user.comments.size > 100 user.award(self) end end end
不同的成就是Achievement
模型的所有子类,并使用单表inheritance,因此它们只存储在一个表中。 子类可以包含每个单独成就所需的所有逻辑。 您还可以在此模型中存储更多信息,例如获得成就的date。 要确保数据库拒绝重复的成绩,可以在type
和user_id
列上创build一个UNIQUE
索引。
CommentAchievement.check_conditions_for(user)
可以随时调用。 您可以创build一个随时运行的后台作业,也可以创build一个观察者:
# app/models/comment_achievement_observer.rb class CommentAchievementObserver < ActiveRecord::Observer observe :comment def after_create(comment) CommentAchievement.check_conditions_for(comment.user) end end # config/environment.rb config.active_record.observers = :comment_achievement_observer
以上只是如何做的一个想法,当然也可能有其他的。 代码只是一个例子,我没有实际testing过。 希望对你有一些帮助。
我为这个任务写了一个Rails 3gem,这个gem适用于徽章,积分和排名。 你可以在https://github.com/tute/meritfind源代码。;