状态机的问题是他只能表达一个状态,比如我在帖子里提到的图例,比如:提请假,报直属领导同意,同时 报 HR 专员同意,然后抄送部门负责人,最后申请人确认后生效。并行的两个步骤。状态机就无法实现了。PetriNet 没有这问题
正因为看过一圈没有所以我才做的吧
我调研过,我做的应该是全网独家。。。
合并进核心没必要,企业级 Rails 项目框架还有 http://trailblazer.to/,也提供了一些针对特定场景的重要轮子。
其实 ActionCable、ActiveStorage 之类默认包括在 rails 里,其实他们根本就不算 rails core 的,从这几个组件的设计上讲,都是 rails 的 engine。
Rails 的核心是 Railtie —— 工具链、ActionPack —— 控制器和视图(的接口)、ActiveModel 和 ActiveRecord —— 模型和 CRUD
其他都是外围,放在一起可以说是 rails team 的工程和宣传上的策略。
另外那些组件从 Basecamp 抽出来的,又 Rails team 和 Basecamp dev team 有很多交集,所以约等于 Rails 官方维护这些组件。
工作流是个很宽泛的概念,审批系统算,如果你看 Wiki,容器编排、CI 的 pipeline 也都可以算,不同的工作流系统设计上有他的侧重点,所以可复杂可简单,但本质上,(不是很精确的解释哈)都在解决流程的定义和流程的执行这两件事。
流程定义就是说设计一种数据结构,来表达业务流程,通常来说最后会落地成一张有向图,文中提到的 PetriNet 相当于是一种为(侧重于审批系统)工作流优化的图结构。实际系统中,由于流程可能会非常复杂,或者说需要可视化的与业务方人员沟通,这时就涉及到了流程的建模。
这里插一句:你提到的 BPMN 就是一种标准化的流程建模语言,他定义了业内专家总结出的业务系统中的流转方式,并且有比较完善的生态:可以被一些流程引擎读取以及流程设计器。但是缺点也明显,“企业级”有时候和“复杂”是挂钩的,而且因为标准定义只包含了业内共识的部分,各家会给自家的 BPMN 方言加大量的私货。
流程执行就是核心功能了,简单的说就是读进流程定义,创建流程的实例(用来持久化流程相关的用户数据和状态),根据流程和实例的状态来执行流程。
认同这两点,结合业务,从头设计一套针对需求的工作流系统并不难,比如 hooopo 提过他那边业务类似电商,流程简单用状态机糊一个就行了,知人曾经魔改的 Netflix/Workflowable 。
至于 SaaS,之前看过 Kissflow,还不错,纯收费的,国内用可能不太接地气。
至于开源项目,工作流是 Java 和 C# 的传统阵地,比如 jBPM 和衍生出来的 Activiti、Flowable。jBPM 和他衍生品的特点是他自身就是一套完整的服务,并且暴露 Restful API,所以你可以把他们作为核心,然后外围构建自己的系统。
缺点很明显了,因为是独立的服务,跟业务系统的数据上的交互和同步会非常难做,数据出了问题对于审批系统,后果挺严重的。
我对审批系统的理解是由三部分组成:表单、权限、流程。你直接看 jBPM 的组件图,大致也是 流程、表单、用户和权限 基本跟我的理解是一致的。
所以这就是我做了一系列轮子的动机,有了这些轮子,就可以直接做在一个系统里了,同时通过组件化的方式明确边界。
最后说工作流在 Ruby 和 Rails 上的生态,我也在一直调研,可能我做的这套轮子是整个 Rails 社区独家,而且除了 WorkflowCore 其他组件都被一些团队(商业产品)验证过了,WorkflowCore 算是我个人对这个领域的总结,如正文所说,还是比较早期,我因为不在做这个领域了所以要暂时放下,但是思路上是没问题的。
你可以参考我上边提到的一些项目,也可以了解 WorkflowCore 原理后复制他示例的代码来构建你的系统,我个人经验看,Rails 做这个比 Java 那些开发效率要高很多,写起来也容易。
PS: 我记得 13 年读大四的时候,帮同学看过他的毕设,他正好是实习做 HIS 系统,基于 Rails 2.1
其实技术会议主要还是社交的,技术分享只是个幌子(不然怎么把这帮死宅骗到一起来
开在美国的会就没便宜的...默默看推...
更新了一下性能测试,随便抄了个 fib 的代码,跑了求第 100 项,3ms 可以的,比我原文中描述的快了非常多,可能是 mruby 1.4.1 带来的,我原始的实验好像还是在 1.3 上
Heroku 涉及 C 扩展可以参考下 sassc-rails 提供的方案 https://github.com/sass/sassc-rails#deployment-to-heroku
metapolit 需要 2.4.1 那你也 rvm install 2.4.1 然后 use 2.4.1 不确定你安装 metaploit 的方式是否兼容 rvm,感觉你可以搜一下再确认,如果是 git clone 或者 gem 安装,那么问题应该不大
如果你 metaploit 是 apt 安装,rei 说得方法可能更稳一些
看了你补充的内容,你 gem install 不要 sudo,这样就切到 root 用户去了
rvm use 2.5.3 这样我没遇到过问题,只要 ruby 装对了
我知道的坑一个是安装前导入 rvm 的证书,另一个就是你主帖里描述的 你安装完之后关掉终端重新开 rvm 应该就正常了,然后再安装 ruby
另外看你截图 ubuntu 版本不是比较新的,如果学习没特殊需要的话上 18.04 吧,16.04 也还可以用,再老会发生什么就不好说了
terminal 设置里把那个用登录 shell 的选项打开
不给咱们那个表单项目加上吗
对呀~~ 所以后来的几个轮子的标题就是“SaaS 快速开发套件”
还差界面和部署
我有一个试验用的项目是需要租户的部分显式调 with_tenant(tenant)
scope,控制器层的做法一样,写起来麻烦一些。
default_scope
就怕有的 gem 比如软删除,会覆盖 default_scope
的行为,出现泄露很难调试
动态表单的数据库定义这块应该做法没太大差异,这块创新的空间感觉不大。
FormCore 主要集中在改善动态表单的开发体验上,没看视频,讲稿中对数据验证、嵌套表单(我觉得这个是一个比较麻烦的部分)似乎没涉及到
另外金数据使用 MongoDB,在存储上优势很大,不过持久化和索引也是个大话题
BTW:话说我看到有人 fork 了 FormCore 把 backend 改成 MongoDB,金数据要不要试试
只扫了眼图,感觉是通过数据库中间件或者是做在数据库层面上了,现在多租户有多数据库、数据库的内建做租户功能、应用层隔离。应用层隔离的轮子间也有实现差异。金数据这套应该是应用层面的多租户,可控性最好,缺点就是涉及数据库相关的操作代码要写对,不然会发生泄漏。其他层面的方案都有坑,太底层了解决起来麻烦
我在想如果搞一个关于 Ruby 或者 Rails 的 AMA(Ask Me Anything)会不会有帮助?主要旨在了解使用者的问题
试试 class ::Spec
注意用 ::
指定下顶层
恰恰相反 Ruby 只有引用类型
感觉这位楼主 2016 年和 2018 年不是一个人
另外我在设计这个模式的时候,研究过 Rails 4 - 5 的 ActiveModel 的演进,预判 ActiveRecord 会把更多的功能移动到 AM 中去,果不其然,最关键的显式声明字段 DSL attribute
和储存字段的 AttributeSet
都挪到了 AM 中,也就是说,Rails 6 发布后,DuckRecord 就完成历史使命了,当然我准备到时候做一套 AM 的扩展来加入嵌套模型的支持
ActiveType 可以,理论上可以移植到 DuckRecord,我没做这个主要俩原因,首先是懒,其次是其实我没想通这样做的场景,比如 ActiveType 文档里演示的注册表单的情况(SignUp 虚拟模型继承 User 模型),我来做的话,直接面对业务的部分我更倾向显式声明字段,这样维护性才高。
至于命名啥的,我觉得靠命名规范可以解决,Rails 本身就是这样做的嘛。
虚拟模型这个手法是基于 Rails 有 ActiveModel 这个公共接口,所以如果你有这方面需要可以直接用 ActiveType,不影响这套设计模式的应用
其实 duck_record 支持和真实模型的关联,比如有一个真实模型 Post
,建立关联可以这样
class VirtualPost < DuckRecord::Base
attribute :post_id, :integer
belongs_to :post
end
应该就可以了,不过我后来反思过,虚拟模型和真实模型的关联可能会有很多边界情况,所以我在 FormCore 的例子里把所有这种写法都改写掉了,在 Presenter
层根据虚拟模型里的字段值去做查询获取真实模型的数据
比如附件字段的 [AttachmentFieldPresenter](https://github.com/rails-engine/form_core/blob/master/test/dummy/app/presenters/fields/attachment_field_presenter.rb 这里我嫁接的 ActiveStorage
因为我跟中国 Py 社区的组织者(们)认识啊
你说 foo *[1, 2, 3]
?
这些年的语言,都在避免 ++
--
,比如 Swift、Rust,Go 虽然有,但是也有人提议在 Go 2 删掉,用 var += 1
写法代替,当然不同意的人也有很多
如果禁用 AP 并且不用 Webpacker 或者其他关联前端工具链的方案的话,你就只能把编译好前端资源放到 public 目录下了,这个就是 Rails 3.1 前的做法,目前 Redmine 这些上古项目也还是这么用(貌似)