ActiveRecord Rollback пропускает ошибки уровня модели в ответ - PullRequest
0 голосов
/ 11 января 2019

Вот код из действия контроллера (Rails 3.2), Пользователь является родителем и имеет ассоциацию has_many с Плакатом и Картой. Если пользовательский объект не удается сохранить, я хочу вернуть все выполненные запросы.

В настоящее время @user.update_attributes! выдает исключение ActiveRecord для любой ошибки и происходит откат.

Наряду с откатом, я хочу, чтобы ошибки от других объектов (дочерние зависимости) также отправлялись как ответ, который пропускается, поскольку код никогда не будет входить в другую часть при исключении.

def update
  @user = User.includes(:posters).includes(:cards).find(params[:id])
    respond_to do |format|
      format.json do
          ActiveRecord::Base.transaction do
            @user.cache_background_data
            @user.disable_messages
            @user.selected_tgs = params["up"] && params["up"]["s_tgs"]
            if @user.valid? && @user.update_attributes!(ng_user_params)
              render :json => Oj.dump(user_as_json(@user), mode: :compat)
            else
              render :json => Oj.dump({:errors => @user.errors}, mode: :compat)
            end
          end
      end
   end 
end     

Я попытался обработать это, используя приведенный ниже код, с помощью команды rescue, в этом процессе откат не запускается. Можно ли принудительно обработать откат (raise ActiveRecord::Rollback) и все пользовательские сообщения об ошибках ActiveRecord, добавленные в ответ?

 rescue ActiveRecord::ActiveRecordError => e
   ng_collect_errors
   render :json => Oj.dump({:errors => @user.errors}, mode: :compat)

В настоящее время с использованием нескольких опций помощь не помогла, поскольку откат не может быть пропущен.

1 Ответ

0 голосов
/ 11 января 2019

Попробуйте поднять откат вручную

ActiveRecord::Base.transaction do
  @user.cache_background_data
  @user.disable_messages
  @user.selected_tgs = params["up"] && params["up"]["s_tgs"]
  if @user.valid? && @user.update(ng_user_params)
    render :json => Oj.dump(user_as_json(@user), mode: :compat)
  else
    render :json => Oj.dump({:errors => @user.errors}, mode: :compat)
    raise ActiveRecord::Rollback
  end
end
...