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