我从http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/得到了这个想法
这是一个小例子:
class PackagesService def self.get_package(package_id) raise ArgumentError.new("package_id can't be nil") if package_id.blank? package = API::get "/packages/#{package_id}" package = JSON.parse package,:symbolize_names => true unless package.blank? end end
是否有任何良好的模式来处理验证和/或抛出Service对象的错误?
验证码:
>我必须检查所有的输入为零或错误的类型.有什么办法容易验证吗?也许是铁路延伸?
出错:
>我可以抓住所有的API错误,然后安全地返回一个零.但使用服务对象的程序员可能不知道nil的含义.
>我可以抓住API错误,并引发另外一个错误,这意味着在所有功能中都可以做到这一点
>第三个选项是保持原样,让程序员处理所有的API错误.
让我知道,如果你知道任何好的模式,或者你有更好的想法来连接一个API.
解决方法
Your linked article实际上提到了这些(参见“提取表单对象”).我有时会使用这样的东西来构建服务对象,例如.
require 'active_model' require 'virtus' class CreatePackage include Virtus include ActiveModel::Validations attribute :name,String attribute :author,String validates_presence_of :name,:author def create raise ArgumentError.new("Invalid package") unless self.valid? response = JSON.parse( API::post("/packages",self.attributes),:symbolize_names => true ) Package.new(response) end end class Package include Virtus attribute :id,Integer attribute :name,String end # eg. service = CreatePackage.new( :name => "Tim's Tams",:author => "Tim",) service.valid? # true; if false,see service.errors package = service.create package.attributes # => { :id => 123,:name => "Tim's Tams",:author => "Tim" }
在例外情况下,我会将它们按原样放在较小的动作上(像这个服务类).如果我正在写一些更实质的东西,如整个API客户端库,我将会包装它们.
我永远不会回到零.像网络错误,或者服务器的错误或不可稀释的响应都会受益于显式错误.
最后,还有一个更重的方法叫做use_case.即使你不使用它,它有一堆想法来解决你可能会感兴趣的服务对象,验证和结果.
编辑:另外,查看Mutations.像use_case,除了更简单和更全面.
原文地址:https://www.jb51.cc/ruby/266990.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。