Исключение ActiveRecord не выбрасывается в объекте службы - PullRequest
0 голосов
/ 09 мая 2018

При создании объекта службы исключение 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

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Вы могли бы обработать это просто в одну строку (здесь для удобства читаемость разбита на две):

def perform   
  OpenStruct.new(success?: account.save, user: user, 
                 account: account, error: account.errors)
end

ЕСЛИ post_account_create можно было бы переместить в модель, которая, как я полагаю, была бы более естественным домом для нее , т.е.

account.rb

after_create :post_account_create

Подробнее о жизненном цикле здесь .

account.errors вернет пустой массив, если его нет, который не должен быть трудным для обработки в другом месте на основании его пустоты или успеха ответа.

Надеюсь, это полезно.

0 голосов
/ 09 мая 2018
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...