Объекты обслуживания рельсов
Я использую сервисные объекты, чтобы абстрагировать функцию оплаты в виде отдельного класса. Я использую этот метод 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), так что посмотрите.
В конце я пошел с подходом rescue_from, и он хорошо работает для меня. Дайте мне знать, как вы поживаете, так как я очень заинтересован в этой области. И если вам нужны примеры кода, дайте мне крик.