微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ruby-on-rails – 服务对象的验证和错误处理

我在Rails中创建了一个服务对象,作为我们的应用程序和API之间的界面.

我从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.

解决方法

对于简单的例子(例如,只有一个参数),那么你的ArgumentError的检查和加注就可以了.一旦你开始复杂的情况(多个参数,对象等),我开始倾向于 VirtusActiveModel Validations.

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 举报,一经查实,本站将立刻删除。

相关推荐