在构建服务对象时,应该没有抛出RecordInvalid
异常。相反,每次都会运行else
块中的代码。
# services/new_registration_service.rb
class NewRegistrationService
...
def perform
begin
account_create
rescue ActiveRecord::RecordInvalid => exception
OpenStruct.new(success?: false, user: user, account: account, error: exception.message)
else
# this is running every time
OpenStruct.new(success?: true, user: user, account: account, error: nil)
end
end
private
...
def account_create
# this is NOT saving, which I believe should
# throw the exception in the perform method
post_account_setup if account.save
end
...
end
这就是我在我的规范中运行的内容,其中需要account: name
:
post :create, params: { account: FactoryBot.attributes_for(:account, { name: nil }) }
即使我puts
返回了account.name
值,它也是nil
...这应该是RecordInvalid
例外的原因。
# models/account.rb
class Account < ApplicationRecord
resourcify
has_many :users
validates :name, presence: true
end
有什么想法吗?
答案 0 :(得分:4)
def account_create
# Instead of this:
post_account_setup if account.save
# Do this:
account.save!
post_account_setup
end
调用save
代替save!
不会引发异常;它只会返回false
。
或者,有人会争辩说使用异常来控制这样的流程是不好的做法。所以相反,你可以这样做:
def perform
# ...
if account.valid?
account.save! # This should never fail!
post_account_create
OpenStruct.new(success?: true, user: user, account: account, error: nil)
else
OpenStruct.new(success?: false, user: user, account: account, error: account.errors)
end
end
或者,类似地:
def perform
# ...
if account.save
post_account_create
OpenStruct.new(success?: true, user: user, account: account, error: nil)
else
OpenStruct.new(success?: false, user: user, account: account, error: account.errors)
end
end
答案 1 :(得分:1)
你可以简单地在一行中处理这个(为了便于阅读,这里分为两个):
def perform
OpenStruct.new(success?: account.save, user: user,
account: account, error: account.errors)
end
IF post_account_create
可以转移到模型中,我建议它是more natural home for it,即
<强> account.rb 强>
after_create :post_account_create
有关生命周期的更多信息here。
如果没有任何内容, account.errors
将返回一个空数组,根据其空虚或响应的成功情况,其他地方难以处理。
希望这很有用。