如何在 RoR 中实施成就系统

2024-05-11

我正在尝试在我的 Ruby on Rails 应用程序中实现一个成就系统,但效果很差。

我有一长串想要检查的成就。所有这些都是由各种控制器中的某些创建操作触发的。

我的想法是我将拥有一个成就模型,其中包括控制器及其响应的操作。然后对创建进行之前过滤并检查适用的成就。当涉及到实际定义/执行成就时,我陷入了困境。每个成就可能需要不同的数据。例如,一个人想知道用户回答了多少个问题,另一个人想知道他们发表了多少条评论,第三个想知道用户邀请的有多少人做出了回应。

实际上将所有必要的 ruby​​ 代码直接嵌入到数据库中是最好的做法吗?我可以看到做一个自包含的块来执行所有活动记录查找等并返回 true/false,尽管我们仍然存在一些关于提前了解设置的问题(即 current_user 等)。

有什么合理的最佳实践不会让我觉得肮脏吗?我可以看到完整的策略/规则引擎是一条路径,尽管这可能比计划a更让我害怕。

谢谢! 奥伦


我同意你的想法,使用Achievement model.

不过,您可能不应该在控制器中实现触发器。想象一下,您有两种发表评论的方式;你将不可避免地得到代码重复。这种行为属于模型。

假设您想要跟踪用户发表的评论数量,并为 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模型,并使用单表继承,以便它们仅存储在一张表中。子类可以包含每个单独成就所需的所有逻辑。您还可以在此模型中存储其他信息,例如授予成就的日期。为了确保数据库拒绝重复的成就,您可以创建一个UNIQUE上的索引type and user_id列。

CommentAchievement.check_conditions_for(user)您可以随时拨打电话。您可以创建一个时不时运行的后台作业,也可以创建一个观察者:

# 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

以上只是一种思路,当然可能还有其他的。代码只是一个例子,我还没有实际测试过。希望对您有一定的帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 RoR 中实施成就系统 的相关文章

随机推荐

  • Linux命令列出所有可用命令和别名

    是否有一个 Linux 命令可以列出该终端会话的所有可用命令和别名 就好像您输入 a 并按下 Tab 键一样 但针对的是字母表中的每个字母 或者运行 别名 但也返回命令 为什么 我想运行以下命令并查看命令是否可用 ListAllComman
  • 2D 中的大量旋转

    我正在尝试使用 Bevy 0 3 并且我可以轻松使用内置转换Camera2dComponents default 这是自上而下的二维 问题在于尝试将玩家的旋转与鼠标同步 for event in evreader iter cursor m
  • Spring-data-cassandra:创建名称为“sessionFactory”的 bean 时出错,并且无法解析对 bean“cassandraTemplate”的引用

    我有一个 springboot 应用程序 在其中连接到 cassandra DB 我的 pom xml parent gt
  • 在 TFS 2012 中使用持续集成进行自动部署

    我已经为 WCF 项目设置了持续集成 并希望使用 MSBuild 参数自动将应用程序部署到远程服务器 但它没有部署 运行新的构建时 所有测试都会通过并且所有项目都会构建 但网站尚未部署 另外 我没有从构建中收到任何错误 表明出现了任何问题
  • 如果在构造函数中使用 super 调用重写方法会发生什么

    有两个班级Super1 and Sub1 超1级 public class Super1 Super1 this printThree public void printThree System out println Print Thre
  • 具有多个注释的方法上的 AspectJ 切入点

    使用加载时编织 纯 AspectJ 我们有2个注释 Time and Count 以及一些带注释的方法 Time name myMethod1Time Count name myMethod1Count public void myMeth
  • 更新或插入 MySQL Python

    如果记录已存在 我需要更新一行 如果不存在 我需要创建一个新记录 我理解 ON DUPLICATE KEY 将使用 MYSQLdb 完成此操作 但是我无法使其正常工作 我的代码如下 cursor database cursor cursor
  • 在VB.NET中获取文件修改日期

    我的文件夹中有许多文件 我需要获取最后修改日期 所以我用了 FDate IO File GetLastWriteTime FName 对于某些文件 它工作正常 但对于其他文件 我得到的日期为 1 1 1601 但是当我在 Windows 资
  • Tkinter:通过多处理启动进程会创建不需要的新窗口

    我计划围绕数值模拟编写一个小型 GUI 这就是我现在使用 Tkinter 的原因 模拟应在单独的进程中从 GUI 启动 为了玩一下 我定义了一个函数 random process 来生成成对的 randn 数字 这应该是一个真正的模拟过程
  • 在Python中将用户昵称转换为正式名字

    我正在尝试根据 Python 中的用户名字和姓氏映射来自不同系统的用户 一个问题是 名字在很多情况下都是 昵称 例如 对于用户来说 他的名字在一个系统中是 Dave 而在另一个系统中是 David python 中有没有简单的方法可以将这些
  • 将两个sql查询合并为一个查询

    如何组合以下 2 个查询以便获得两列 PAYMODE 和付款类型 两个查询都很相似 并且针对同一个表 将两个 sql 查询合并为一个查询 这样我就不需要执行两个单独的查询 SELECT ETBL DESC TXT as PAYMODE FR
  • “array.map”是否保留原始顺序?

    我有一个User类has many Jobs 我使用以下代码映射作业 def ranges user jobs map u u start at u end at end 我有一个比较两个数组的规范 my array start1 end1
  • Winform DatagridView 数字列排序

    我只使用一个简单的 DataGridView 来保存一堆数据 有趣的是 我在特定列中有小数 但是当按小数列排序时 它的排序是错误的 例如 起始顺序可能是 0 56 3 45 500 89 20078 90 1 56 100 29 2 39
  • 创建 df 以生成给定格式的 json

    我正在尝试生成一个 df 来生成下面的 json Json数据 name flare children name K1 children name Exact size 4 name synonyms size 14 name K2 chi
  • 对 ExecuteNonQuery() 的单次调用是原子的

    对 ExecuteNonQuery 的单次调用是否是原子的 或者如果单个 DbCommand 中有多个 sql 语句 那么使用事务是否有意义 请参阅我的示例以进行说明 using var ts new TransactionScope us
  • @UniqueConstraint 和 @Column(unique=true) 选项之间的 Doctrine ORM 级别差异

    在数据库级别 使用一个选项与另一个选项来定义时没有区别独特性如下所示 虽然 UniqueConstraint在其文档中读取 它仅在 SchemaTool 模式生成上下文中有意义 两者之间是否存在 ORM 级别差异 我的意思是 当我们运行查询
  • 使用材质 UI 更改反应选择中的禁用属性

    我正在尝试使用材料用户界面更改反应应用程序中选择按钮单击的禁用属性 我的按钮代码是
  • perf stat中的cycles注释是什么意思

    8 014196 task clock 0 004 CPUs utilized 204 context switches 0 025 M sec 32 cpu migrations 0 004 M sec 0 page faults 0 0
  • 不理解..密度的行为

    在下面的数据框中 我预计密度的 y 轴值为 0 6 和 0 4 但它们是 1 0 我觉得我使用的方式显然缺少一些非常基本的东西 密度 但是我的大脑冻结了 我将如何使用 密度 获得所需的行为 任何帮助将不胜感激 df lt data fram
  • 如何在 RoR 中实施成就系统

    我正在尝试在我的 Ruby on Rails 应用程序中实现一个成就系统 但效果很差 我有一长串想要检查的成就 所有这些都是由各种控制器中的某些创建操作触发的 我的想法是我将拥有一个成就模型 其中包括控制器及其响应的操作 然后对创建进行之前