如题:
比如。新会员注册,+20 积分。 每天登陆, +5 积分。 评论, +2 积分。诸如此类。
我的想法很原始,在每个能获取积分的页面动作上,到 controller 里《用户积分表》登陆一条相关用户的纪录。
请问各位大神,有什么思路。去做这块业务。
刚才发现了 @huacnlee 大神写的一篇帖子。https://ruby-china.org/topics/3571。 推荐了这个。https://ruby-china.org/topics/3571 。 打算先看看。
#1 楼 @tracyzhang merit 蛮赞的,但是不足的是需要分散地关注各种 action。可以考虑另一种思路,就是用 auditing 相关的技术监视积分改变 (积分改变才是问题根源),每次记录下改变原因。相关的 gem 有: https://github.com/airblade/paper_trail 以及 https://github.com/chaps-io/public_activity 。我去年用过 paper_trail 实现了一套员工的积分系统。结合 i18n 之类的可以实现非常灵活的积分登记系统。
@martin91 谢谢。我看了下 paper_trail 的文档。思路确实不一样,没有 merit 那么浅显易懂。哈哈。 但还是谢谢,我想先用 merit 来试试。之后再用你推荐的做做看。
@rei 听起来是过来人的经验,不用考虑太多,just do it. 不管怎样,先跑起来,不是什么特殊的需求,慢慢打磨改进,花这点时间纠结,可能你已经实现了功能了,并且可以跑得很好。
我的网站 qiutu.org 就是用的 merit,不过我只用来做徽章这部分功能。我的积分规则很简单,就是用户每次打卡,根据动作难度获取相应的积分,所以这部分是手写,一个 before_action 就搞定了,觉得 merit 完全可以满足你的业务需要。
#18 楼 @peter 就是把消息作为内容,在代码里边只用一些必要的 key,避免代码中硬编码:
首先是先为各个事件定义好消息模板,我们约定所有事件对应的消息在 yaml 中的格式是 "%{language}.events.%{event_name}":
# config/locales/zh-CN.yml
zh-CN:
events:
new_order: "新建需求"
start: "进入交付阶段,负责人:%{person_in_charge}"
# ...
接着定义方法,这个方法其实只是实现了上面的约定,即所有事件的消息都从 "events.#{event}"
这个 key 读取。
# app/models/concerns/order_auditing.rb
class OrderAuditing
extend ActiveSupport::Concern
# 返回某个事件的审计记录内容
# @param event [Symbol, String] 时间名称, e.g. "new_order"
# @param options [Hash] optional 额外的信息,此参数将会直接传递给底层的 I18n,用于直接渲染人类可读的信息
# @return String 对应 event 的消息内容, e.g. "新建需求", or "进入交付阶段,负责人:黄晓明"
def event_message(event, options = {})
I18n.t("events.#{event}", options)
end
end
最后的用法就是:
class Order < ActiveRecord::Base
# callback 的逻辑根据实际需求写,这里仅为示例,非真实代码
before_transition on: :new do |transition, _|
self.paper_trail_event = event_message(:new_order) # 相当于 `self.paper_trail_event = "新建需求"`
# or
# self.paper_trail_event = event_message(:start, person_in_charge: user.name) # 相当于 `self.paper_trail_event = "进入交付阶段,负责人:xxxx"`
end
end
实际上就是将消息内容与代码本身分离,很多场景下我都是使用 i18n 的文件来处理这种“事件 - 消息”的映射关系的。
写完才感觉,自己又班门弄斧了!