Rails服务对象

时间:2013-10-10 12:55:45

标签: ruby-on-rails ruby-on-rails-3 stripe-payments service-object

我正在使用服务对象将条带支付功能抽象到它自己的类中。我正在使用ryan bates谈到的这种方法https://gist.github.com/ryanb/4172391

class Purchase
  def initialize(order)
    @order = order
  end

  def create_customer
    customer = stipe create customer
    if customer
       charge_customer(customer)
    else
       stipe error in creating customer
    end
  end

  def charge_customer(customer)
      if charge is sucessfull
         update_order(charge details)
      else
         stripe error in charging card
      end     
  end
  def update_order
     @order.update(payment attributes)
  end
end

然后在订单控制器中,我正在做类似

的事情
def create
@order = Order.new(params[:order])
 if @order.save
    payment = Payment.new(@order)
 else 
   render 'new' with flash message "payment error"
 end
end

我的问题是,如何向用户显示stipe错误消息(“创建客户时出现问题”和“充电卡中的条带错误”)? 或者我可以在订单模型中调用服务对象并将其添加到订单错误消息中吗?例如,
订单控制器

@order.save_with_payment

订单型号

def save_with_payement
   payment = Payment.new(self)
   #update order 
   self.payment_token = payment.token
   etc
end

如果我能用模型做到这一点,如何进行显示条纹错误的验证?
提前谢谢。

4 个答案:

答案 0 :(得分:2)

首先尝试尽可能地分开关注点。它已经感觉你的购买/支付类做得太多,可能它应该将其部分例程委托给其他服务对象。

其次,我同意phoet。我没有看到你不会将params hash传递给服务对象的原因。在我们最新的项目中,我们完全依赖于我们称为工厂的服务对象来生成/操纵我们的模型对象。在你的情况下你可以这样做:

class OrderFactory
  def self.create(params)
    new(params).create
  end

  def initialize(params)
    @order = Order.new(params[:order])
  end

  def create
    @payment = Payment.new(self)
    @order.payment_token = payment.token
    #....
  end
end

谈论验证 - 您可以向纯Ruby对象添加验证方法。例如,通过使用ActiveModel: http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord/ 然后,您可以创建自定义验证器like Ryan suggested

或者您可以使用像Virtus这样的gem,并添加一些自定义验证规则。

答案 1 :(得分:0)

我认为该服务应负责处理所有这些。所以它可能看起来像这样

def create
  @payment = Payment.new(params[:order])
  if @order = @payment.execute_transaction
    [...]
  else 
    [...]
  end
end

因此,支付服务将处理创建和持久订单,也可能会添加验证错误。您还可以返回某种@result对象,该对象可能包含顺序和依赖错误消息。

答案 2 :(得分:0)

前一天我问了一个非常相似的问题。我收到的回复确实非常有用(归功于@ gary-s-weaver)所以请看一下。

Rails generic errors array

我最终采用了rescue_from方法,对我来说效果很好。让我知道你如何继续,因为我对这个领域很感兴趣。如果你需要任何代码样本,请给我一个大喊。

答案 3 :(得分:0)

我为服务对象编写了一个gem。查看peafowl gem。