Home > Blockchain >  Rails 7: How to check from outside transaction block if record was updated successfully
Rails 7: How to check from outside transaction block if record was updated successfully

Time:12-23

I've searched through the rails docs but not find any method which can check if record was corectly updated from outside transaction block because I dont want to put respond_to block into my transaction because it is bad practise. Is there any method like persisted? which I use with create/save method...

def update
  ActiveRecord::Base.transaction do
    address = Address.find_or_create_by(address_params)
    @invoice_account = InvoiceAccount.find_or_create_by(invoice_account_params
                                                          .merge({ :invoice_address_id => address.id }))
    @invoice = Invoice.find_by_id(params[:id])
    @invoice.update(invoice_params.merge({ purchaser_id: @invoice_account.id }))
  end

  respond_to do |format|
if @invoice.method `some method to check if invoice was updated`
      format.html { redirect_to invoice_url(@invoice), notice: "Invoice was successfully updated." }
      format.json { render :show, status: :ok, location: @invoice }
    else
      format.html { render :edit, status: :unprocessable_entity }
      format.json { render json: @invoice.errors, status: :unprocessable_entity }
    end
  end
end

CodePudding user response:

I just edit my code as bellow, capture result of the transaction to variable is_updated. When in transaction error occurred then is_updated would be false and changes are rolled back. If no error occurred is_updated true.

def update
  is_updated =
  ActiveRecord::Base.transaction do
    address = Address.find_or_create_by(address_params)
    @invoice_account = InvoiceAccount.find_or_create_by(invoice_account_params
                                                          .merge({ :invoice_address_id => address.id }))
    @invoice = Invoice.find_by_id(params[:id])
    @invoice.update(invoice_params.merge({ purchaser_id: @invoice_account.id }))
  end

respond_to do |format|
  if is_updated
    format.html { redirect_to invoice_url(@invoice), notice: "Invoice was successfully updated." }
    format.json { render :show, status: :ok, location: @invoice }
  else
    format.html { render :edit, status: :unprocessable_entity }
    format.json { render json: @invoice.errors, status: :unprocessable_entity }
  end
end end

CodePudding user response:

Calling .update on an ActiveRecord object will return true if it was able to store it to db or false if any error occurred. I'd take advantage of that and store its result on a variable, like the following:

def update
  updated = false

  ActiveRecord::Base.transaction do
    address = Address.find_or_create_by(address_params)
    @invoice_account = InvoiceAccount.find_or_create_by(invoice_account_params
                                                          .merge({ :invoice_address_id => address.id }))
    @invoice = Invoice.find_by_id(params[:id])
    updated = @invoice.update(invoice_params.merge({ purchaser_id: @invoice_account.id }))
  end

  respond_to do |format|
    if updated
      format.html { redirect_to invoice_url(@invoice), notice: "Invoice was successfully updated." }
      format.json { render :show, status: :ok, location: @invoice }
    else
      format.html { render :edit, status: :unprocessable_entity }
      format.json { render json: @invoice.errors, status: :unprocessable_entity }
    end
  end
end
  • Related