Search code examples
ruby-on-railsrubyruby-on-rails-4braintree

refresh Drop-in UI after error - Braintree/Rails


I am using the Braintree api and its Drop in UI which is working fine until i get an unsuccessful response.

The drop in ui is not refreshing (maybe there is something i need to do) which results a user not being able to enter new card details. I don't want to persist the card details, just show the form again

I am not using turbolinks

def new
  gon.client_token = generate_client_token
end

def create
  @result = Braintree::Transaction.sale(
            amount: amount,
            payment_method_nonce: params[:payment_method_nonce],
            customer: {
              first_name: params[:first_name],
              last_name: params[:last_name]
            options: {
              submit_for_settlement: true
            }
          )
  if @result.success?
    redirect_to thank_you_path
  else
    @error_message = BraintreeErrors::Errors.new.error_message(@result)
    flash.now[:alert] = @error_message
    gon.client_token = generate_client_token
    render :new
  end
end

Is there something I need to do to get this to work?

Update

As in the comments I could redirect to the new action, reloading my page, which would then show my drop in ui form, so to expand on this question what if I want to persist the data that as user has filled in on another part of my form, like name, address etc , again i am not worried about the card information

I use a form_tag

<%= form_tag transactions_path, class: 'form-small form' do %>
  <%= text_field_tag :first_name, "", placeholder: 'First Name', required: false %>
  <%= text_field_tag :last_name, "", placeholder: 'First Name', required: false %>
<% end %>

Thanks


Solution

  • You can have your create action redirect_to the new action.

    def new
      @first_name = params[:first_name] if params[:first_name].present?
      @last_name = params[:last_name] if params[:last_name].present?
    end
    
    def create
      ...
    
      if @result.success?
        redirect_to thank_you_path
      else
        redirect_to new_path (
          first_name: params[:first_name], 
          last_name: params[:last_name]
        )
      end
    end
    

    Then you need to update the form so it picks the 'default' values

    <%= form_tag transactions_path, class: 'form-small form' do %>
      <%= text_field_tag :first_name, @first_name, placeholder: 'First Name', required: false %>
      <%= text_field_tag :last_name, @last_name, placeholder: 'First Name', required: false %>
    <% end %>
    

    If you have many such properties it will be cleaner if you bundle them all in a customer_details object. Then in your view you can do

    <%= form_for @customer_details do |c| %>
      <%= c.text_field :first_name %>
    <% end %>