Объекты обслуживания рельсов

Я использую сервисные объекты, чтобы абстрагировать функцию оплаты в виде отдельного класса. Я использую этот метод 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 ("ошибка stipe в создании клиента" и "error stripe error in card card")? Или я могу вызвать сервисный объект в модели заказа и добавить его в сообщения об ошибках заказа? Например,
Контроллер заказов

@order.save_with_payment

Заказать модель

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

Если я могу сделать это с моделью, как мне сделать проверку, которая показывает ошибки полосы?
Заранее спасибо.

4 ответа

Прежде всего постарайтесь разделить проблемы, насколько это возможно. Уже кажется, что класс "Ваша покупка / оплата" делает слишком много, вероятно, ему следует делегировать часть своих процедур другим объектам службы.

Во-вторых, я согласен с Phoet. Я не вижу причины, по которой Вы бы не передавали хэш params объекту обслуживания. В нашем последнем проекте мы полностью полагаемся на сервисные объекты, которые мы называем Фабриками, для производства / манипулирования нашими модельными объектами. В вашем случае вы можете сделать так:

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/ Затем вы можете создавать собственные валидаторы, как предложил Райан.

Или Вы можете использовать драгоценный камень, такой как Virtus, и добавить некоторые пользовательские правила проверки.

Я написал драгоценный камень для служебных объектов. Проверьте драгоценный камень павлина.

Я думаю, что служба должна нести ответственность за все это. так это может выглядеть так

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

таким образом, платежный сервис будет обрабатывать создание и сохранение заказа, а также может добавлять ошибки проверки. Вы также можете вернуть какой-то @result объект, который может состоять из порядка и в зависимости от сообщений об ошибках.

Я задал очень похожий вопрос только один день назад. Ответ, который я получил, был действительно очень полезен (спасибо @gary-s-weaver), так что посмотрите.

Массив ошибок Rails

В конце я пошел с подходом rescue_from, и он хорошо работает для меня. Дайте мне знать, как вы поживаете, так как я очень заинтересован в этой области. И если вам нужны примеры кода, дайте мне крик.

Другие вопросы по тегам