如何在rails中引发ActiveRecord :: Rollback后向用户显示错误?

时间:2017-12-14 18:55:04

标签: ruby-on-rails activerecord

我在创建客户端后创建了一个用户,但是如果用户已经存在,我会回滚该事务,但是如何告知用户通知发生了什么?

到目前为止我已经

def create
    ActiveRecord::Base.transaction do
      @affiliate = Affiliate.new(affiliate_params)
      respond_to do |format|
        if  @affiliate.save
          if User.find_by_email(user_params[:email]).nil?
          @user = User.create!(user_parameter)        
          format.html {redirect_to :back, notice: 'Thanks for your submission'}
          format.json {render :show, status: :created, location: @affiliate}
          else
            raise ActiveRecord::Rollback

          end
        else
          format.html {render :signup, layout: "sign-ups"}
          format.json {render json: @affiliate.errors, status: :unprocessable_entity}
        end
      end
    end
  end

我尝试使用渲染和重定向但没有效果。

2 个答案:

答案 0 :(得分:0)

一般来说,在遇到预期条件和手动回滚时引发异常都会被视为Rails应用程序中的代码异味。

更加惯用的方法可能涉及在将关联企业保存在控制器中之前检查用户的存在,或者将逻辑移动到模型验证中。

答案 1 :(得分:0)

要回答您的具体问题而不重新设计所有内容,您只需检查performed?,因为所有其他路径都会呈现。

def create
  ActiveRecord::Base.transaction do
    ...
      format.html {redirect_to :back, notice: 'Thanks for your submission'}
      format.json {render :show, status: :created, location: @affiliate}
    ...
    else
    ...
      format.html {render :signup, layout: "sign-ups"}
      format.json {render json: @affiliate.errors, status: :unprocessable_entity}
    ...
    end
  end

  unless performed?
    # render duplicate email notice, re-display form
  end
end

那就是说,下面是一种更典型的方法。仍然存在一些微妙的问题,但它们需要深入了解您的应用程序的具体细节。

# Add #email unique validation to User model, if not already implemented.
#   class User < ApplicationRecord
#     ...
#     before_validation :normalize_email # downcase, etc
#     validates :email, unique: true # should unique constraint on DB also
#     ...
#   end

def create
  success = nil

  ActiveRecord::Base.transaction do
    @affiliate = Affiliate.new(affiliate_params)
    @affiliate.save

    # I'm guessing there is a relationship between the Affiliate and
    # the User which is not being captured here?

    @user = User.new(user_params)
    @user.save

    # Validation errors will populate on both @affiliate and @user which can
    # be presented on re-display (including duplicate User#email).

    # Did both the @affiliate and @user validate and save?
    success = @affiliate.persisted? && @user.persisted?

    # If one or both failed validation then roll back
    raise ActiveRecord::Rollback unless success
  end

  respond_to do |format|
    if success
      format.html { redirect_to :back, notice: 'Thanks for your submission' }
      format.json { render :show, status: :created, location: @affiliate }
    else
      # Either @affiliate or @user didn't validate. Either way, errors should
      # be presented on re-display of the form. Json response needs work.
      format.html { render :signup, layout: "sign-ups" }
      format.json { render json: @affiliate.errors, status: :unprocessable_entity }
    end
  end
end