Rails 发布一个 Gem —— ActiveService,给 Rails 添加一个 Service 层

Rei · March 22, 2015 · Last by sufery replied at April 06, 2020 · 4503 hits

https://github.com/chloerei/active_service

安装

在 Gemfile 中添加:

gem 'active_service', github: 'chloerei/active_service'

然后运行:

bundle

使用

定义一个 service:

class HelloService < ActiveService::Base
  def initialize(name)
    @name = name
  end

  def say_hello
    "Hello #{@name}!"
  end
end

生成实例:

hello_service = HelloService.new('David')

执行 Service 方法:

hello_service.say_hello
# => 'Hello David!'

Rails 生成器

如果你在 Rails 中使用,那么可以使用 Rails 的生成器:

rails g service hello

这会生成模版文件,放在 app/servicestest/services

题外话

因为 active_service 这个 gem 名已经被占用了,所以暂时没有 push 到 rubygems 上。如果大家喜欢,欢迎在 github 点 star,如果人数多了我去联系那个作者能不能把名字让给我。(没准 DHH 会把它纳入 Rails 5.0 呢!)

用来做什么?

#1 楼 @huacnlee 让认为 Rails 缺少 Service 层的人获得心灵的安慰。

ActiveService::Base 有啥内容?真要写 service 的话,用 PORO 的方式就 ok 了吧,感觉这么干没啥实际用处

#4 楼 @bluecoda 看看源码。

#5 楼 @Rei ActiveXX 的命名给人提供一种可靠的感觉,生成器能让人觉得这个写法得到官方支持。

这样就完了?我还 watch 准备看下文呢

#7 楼 @zgm 嗯……还需要什么功能吗?

#7 楼 @zgm 这个 gem 应该主要是给那些说 Rails 没有 Service 层支持,所以就没有架构的人用的,告诉他们几行代码让 Rails 支持 Service 层,哈哈

@Rei railtie line 这里没看懂。加 Railtie 类继承 rails 的 railtie 的目的是什么?

你应该在 4 月 1 号发布这个 gem 的

#10 楼 @flowerwrong 作为 rails gem 是要这样初始化的,未来加初始化代码有帮助。

#10 楼 @flowerwrong 继承 railtie 可以实现以下目标:

  • creating initializers
  • configuring a Rails framework for the application, like setting a generator
  • adding config.* keys to the environment
  • setting up a subscriber with ActiveSupport::Notifications
  • adding rake tasks

http://api.rubyonrails.org/classes/Rails/Railtie.html

目前只利用了它自动添加 lib/rails 目录下的 generator 这个功能。

其实写 service 继承 SimpleDelegator 更方便用一些,还能直接调用原对象的方法,而且 initialize 都不用自己写

#16 楼 @aptx4869 有时不止需要一个对象。

分离业务层没错啊,controller 这是负责交互逻辑,当你项目不仅有 WEB,还有客户端,还有 API 的时候,难道要把之前的业务重写一遍?我不明白那些反对 service 层的人,你们是没有写过大项目,还是说没有做到过架构师?!

还有就是,不要以为把业务写在 Model 就是正确的。Model 是持久层逻辑,谁说用 Rails 就一定要用 ActiveRecord?! ActiveRecord 只不过是 POJO + 持久化,写在 ActiveRecord,只会增加耦合。Rails 中虽然不需要 IOC,但是用 ActiveRecord 时,还是应该定义到 service 的最顶层

You need to Sign in before reply, if you don't have an account, please Sign up first.