Correct use of flash [: success]

1

Good afternoon, I need your help.

I need to show a success or rejection message, once I have inserted an object in BD. So far I have only managed to update the browser window, not automatically (as it should be), once the event submit has been triggered.

cotizacions_controller.rb

def create
  @cotizacion = Cotizacion.new(cotizacion_params)

  if @cotizacion.save
    flash[:success] = "Su tasación esta siendo procesada"
  else
    respond_to do |format|
      format.html { render :new }
      format.json { render json: @cotizacion.errors, status: :unprocessable_entity }
    end
  end
end

_header.html.erb

<header>
  <div class="header-content">
    <div class="header-content-inner">
      <h1>Negocia tu Auto</h1>
      <% flash.each do |key, value| %>
        <div class="alert alert-success" role="alert">
          <%= value %>
        </div>
      <% end %>

      <%= render :partial =>'cotizacions/form' , locals: { cotizacion: @cotizacion } %>
    </div>
  </div>  
</header>

_form.html.erb

<%= form_with(model: cotizacion, scope: :cotizacion) do |form| %>
  <div class="container">
    <div class="row">
      <div class="col-md-2">
        <div class="field">
          <%= form.text_field :patente, 
                              placeholder: "Patente", 
                              id: :car_patente, 
                              class: "form-control" %>
        </div>
      </div>
      <div class="col-md-2">
        <div class="form-inline">
          <%= form.select :marca, 
                          options_for_select([["SUBARU", "t"], ["KIA", "s"]], id: :car_marca), 
                          prompt: "Marca", 
                          class: "combobox form-control",
                          name: "inline"%>
        </div> 
      </div>
      <div class="col-md-2">
        <div class="field">
          <%= form.text_field :modelo, 
                              id: :car_modelo, 
                              placeholder: "Modelo Ej: Yaris, i10",
                              class: "form-control" %>
        </div>
      </div>
    </div>

    <!-- ... -->

    <div class="row">
      <div class="col-md-12 col-md-offset">
        <div class="actions">
          <%= form.submit  class: 'btn btn-success btn-lg', value: 'Tasar su Vehículo' %>
        </div>
      </div>
    </div>
  </div>
<% end %>

Expected as an image:

Once the message is displayed, the idea is to show the start page again, after 1 second, without the message and the clean form.

Project structure is as follows.

creatives / index.html.erb

       <%= render 'navbar' %>
       <%= render 'header' %>
       <%= render 'services' %>
       <%= render 'portfolio' %>
       <%= render 'call_to_action' %>
       <%= render 'contact' %>

File quotes / new.html.erb

               <h1>New Cotizacion</h1>

              <%= render 'form', cotizacion: @cotizacion %>

              <%= link_to 'Back', cotizacions_path %>

Routes.rb file

           Rails.application.routes.draw do
              get 'creatives/index'
              root :to => 'creatives#index'
              resources :cotizacions
              post 'creatives/index', to: 'cotizacions#create' 
            end

New behavior

Log file

Started POST "/ creatives / index" for 127.0.0.1 at 2017-08-01 10:00:45 -0400 Processing by CotizacionsController # create as JS   Parameters: {"utf8" = > "✓", "authenticity_token" = > "6Y0r + 8y7M5DJUeF7Gt2CziIEpMef4nLN8s6bvRA9jr + CHN2gRMGFaEzVgX / UnVc2YsCtNCH1DEs6cfi71r3PrA ==", "quote" = > {"patent" = > "congetenriutes", "brand "= >" "," model "=" "," mileage "=" "," mail "=" "," phone "=" "," abs "= >" 0 "," air_conditioned "=>" 0 "," airbag "= >" 0 "," velocity_cruise "=>" 0 "}," commit "= &" Rate your Vehicle "}   [1m [35m (0.1ms) [0m [1m [36mbegin transaction [0m   [1m [35mSQL (0.4ms) [0m [1m [32mINSERT INTO "quotes" ("patent", "brand", "model", "mileage", "mail", "telephone", "abs", "air_conditioned" , "airbag", "speed_strike", "created_at", "updated_at") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?) [0m [["patent" , "congetenriutes"], ["brand", ""], ["model", ""], ["mileage", ""], ["mail", ""], ["phone", ""] , ["abs", "f"], ["air_conditioned", "f"], ["airbag", "f"], ["speed_crucer", "f"], ["created_at", "2017-08 -01 14: 00: 45.399154 "], [" updated_at "," 2017-08-01 14: 00: 45.399154 "]]   [1m [35m (1.7ms) [0m [1m [36mcommit transaction [0m Redirected to link Completed 200 OK in 29ms (ActiveRecord: 3.1ms)

Started GET "/" for 127.0.0.1 at 2017-08-01 10:00:47 -0400 Processing by CreativesController # index as HTML   Rendering creatives / index.html.erb within layouts / creative   Rendered creatives / _navbar.html.erb (0.3ms)   Rendered quotes / _form.html.erb (2.6ms)   Rendered creatives / _header.html.erb (4.3ms)   Rendered creatives / _services.html.erb (0.4ms)   Rendered creatives / _portfolio.html.erb (4.8ms)   Rendered creatives / _call_to_action.html.erb (0.3ms)   Rendered creatives / _contact.html.erb (0.4ms)   Rendered creatives / index.html.erb within layouts / creative (18.2ms) Completed 200 OK in 50ms (Views: 48.8ms | ActiveRecord: 0.0ms)

    
asked by Sebastian Campos Davila 31.07.2017 в 20:57
source

1 answer

1
  

So far I have only managed to update the window of the   browser, ...

When using form_with , you are sending the form with ajax , however the action create of the controller is not responding to the indicated format after successfully saving a quote (i.e. if @cotizacion.save ).

This generates an error on your page (which you should be able to see in the server log) and no action is generated that can call the message flash (ie there is no render or respond_to , only one error), so the flash message is not displayed (even after using flash.now ).

If your interest is to continue using ajax then you must change the flash messages as samples, because with ajax you only update a part of the page (i.e. you should do it manually).

However, I do not think you're looking to use ajax , so I recommend you use the local attribute in your form to avoid it:

<%= form_with(model: cotizacion, scope: :cotizacion, local: true) do |form| %>

And the action create of the controller uses redirect_to 1 :

def create
  @cotizacion = Cotizacion.new(cotizacion_params)

  if @cotizacion.save
    flash[:success] = "Su tasación esta siendo procesada"
    redirect_to cotizacions_path
  else
    respond_to do |format|
      format.html { render :new }
      format.json { render json: @cotizacion.errors, status: :unprocessable_entity }
    end
  end
end

Where cotizacions_path must match the path of the action index .

1 The use of flash is maintained because a redirect_to was added instead of render .

  

The idea, once the message is displayed, is to show the page of   start, after 1 second, without the message and the clean form.

For this you can use JavaScript / JQuery , which will allow you to hide the error message after a certain time; for example, you could do the following to make this happen with any message (or messages) you receive through flash :

_header.html.erb

<header>
  <div class="header-content">
    <div class="header-content-inner">
      <h1>Negocia tu Auto</h1>
      <div id="error">
        <% flash.each do |key, value| %>
          <div class="alert alert-success" role="alert">
            <%= value %>
          </div>
        <% end %>
      </div>

      <%= render :partial =>'cotizacions/form' , locals: { cotizacion: @cotizacion } %>
    </div>
  </div>  
</header>

<script type="text/javascript">
  $(document).ready(function() {
    setTimeout(function() {
      $('#error').animate({ height: 0, opacity: 0 }, 'slow');
    }, 1000);
   });
</script>

An additional div was added to encapsulate the message (or messages) of flash , which you reference in the script (ie $('#error') ) to hide it after the defined time ( ie 1000 ).

flash vs flash.now

With flash the assigned value is maintained until the next request, therefore its use before a redirect_to is recommended; for example:

flash[:success] = "Su tasación esta siendo procesada"
redirect_to cotizacions_path

On the other hand, flash.now only shows the value in the current request (after a render ), eliminating it from the next request, therefore it works only after using render , for example:

flash.now[:success] = "Su tasación esta siendo procesada"
render :index

It is important to note that with flash the available value is also available in the current request (e.g. after doing render ) but the message will not disappear in the next request.

    
answered by 31.07.2017 / 22:48
source