开发:events 实现
Closed this issue · 4 comments
dylanninin commented
主要利用 rails
提供的机制:
- callbacks: 实现生成
event
的 同步回调 - concerns:DRY,减少重复代码;并尝试将
event
抽象成 DSL,降低代码入侵与耦合
ref
dylanninin commented
以 Todo
为例,没有 events
动态之前:
class Todo < ApplicationRecord
enum status: { open: 0, running: 1, paused: 2, completed: 3 }
belongs_to :assignee, class_name: 'User', optional: true
belongs_to :todo_list
belongs_to :project
belongs_to :team
belongs_to :creator, class_name: 'User'
end
要增加 创建
、完成
等events
动态,需要 include Eventable
,并:
class Todo < ApplicationRecord
include Eventable
eventablize_serializer_attrs :name
eventablize_ops_context :create, provider: :project
eventablize_ops_context :destroy
# FIXME: For consistency, set_due rename to set_due_to
eventablize_ops_context :update, verb: :set_due_to, attr: :due_to
eventablize_ops_context :update, verb: :assign, target: :assignee, attr: :assignee_id, old_value: -> (v) { v.nil? }, new_value: -> (v) { v.present? }
eventablize_ops_context :update, verb: :reassign, target: :assignee, attr: :assignee_id
eventablize_ops_context :update, verb: :run, attr: :status, new_value: -> (v) { v == 'running' }
eventablize_ops_context :update, verb: :pause, attr: :status, new_value: -> (v) { v == 'paused' }
eventablize_ops_context :update, verb: :complete, attr: :status, new_value: -> (v) { v == 'completed' }
eventablize_ops_context :update, verb: :reopen, attr: :status, old_value: -> (v) { v == 'completed' }, new_value: -> (v) { v == 'open' }
eventablize_ops_context :update, verb: :recover, attr: :deleted_at, old_value: -> (v) { v.present? }, new_value: -> (v) { v.nil? }
enum status: { open: 0, running: 1, paused: 2, completed: 3 }
belongs_to :assignee, class_name: 'User', optional: true
belongs_to :todo_list
belongs_to :project
belongs_to :team
belongs_to :creator, class_name: 'User'
end
dylanninin commented
Todo
完成了基本的 model 测试用例,见 https://github.com/dylanninin/tower-events/blob/57eb200e6f0a2ff017037788e86b2630b1b0d5b8/spec/models/todo_spec.rb
相比系统设计 #2 中的主要变化:
- verb 变化:
set_due
调整为set_due_to
,与todo
的due_to
保持一致 - audited 单独封装成一个 hash,
event[object][audited]
如:
"audited": {
"attribute": "due_to",
"old_value": nil,
"new_value": "2017-06-03"
}
需要完善的地方:
- 在
audited
中需要获取引用对象,而非 id 值。如todo.assignee
,指定任务的完成者时,此时保存的audited
信息如下:
"audited": {
"attribute": "assignee_id",
"old_value": nil,
"new_value": 1
}
- 在
create
时,是否也可以支持其他event
的创建,比如新建 todo 时,同时制定了完成者、完成时间。此时需要eventablize_ops_context
调整内部实现
dylanninin commented
@zchar 目前 Todo
大致实现了如上的动态,可以 review 下,提一些意见和建议。
dylanninin commented
忘记补充一个问题,软删除时,没有调用 destroy callback。一会儿使用 update 配合 verb old_value new_value 试试