1
votes

I have attempted to do both examples below to display a message once before going to another view.

flash[:success] = "Here is my flash message."    
redirect_to my_path

flash.discard[:success] = "Here is my flash message."    
redirect_to my_path

In both cases the message displays as expected when my_path is displayed. When I leave that view then return to my_path the flash message is still displayed. I can display another view then return to my_path multiple times in my application and the message is still displayed.

I know that using flash.now will not work because I'm not doing a render command.

I have no idea how to change this since every post I have found online regarding this so far says that I should use flash.discard when using redirect_to. I'm not finding anything that says that flash.discard is deprecated in Rails 4. Maybe there is another option in Rails 4 that I'm not aware of.

Any help would be appreciated.

UPDATE 1/18/2014 8:50 am CST

View

<% provide(:title, @page_title) %>
<div class="row-fluid" style="background-color: #ffffff;">
  <div class="span12" align="center">
    <div class="contact-class">
      <div class="contact-form">
        <div class="row-fluid">
          <div class="span8 offset2">
        <p>By joining the 4Dcube3Dcross ™ Mailing List you will receive announcements about new 4Dcube3Dcross ™ website or web app features, new products and promotions.</p>
          </div>
        </div>
        <div class="row-fluid">
          <div class="span6">
            <div class="headings">JOIN</div>
        <%= form_tag maint_mailing_list_path, method: 'get' do %>
          <p style="font-weight: bold;">To Add a new Mailing List entry, enter a Valid Email Address below and click the button:</p>
          <%= text_field_tag :list_email, params[:list_email], :minlength => 2, :maxlength => 70, placeholder: "Valid Email Address (max. 70)" %><br><br>
          <div><span valign="center"><%= submit_tag "Join Our Mailing List", class: "btn btn-medium btn-custom" %></span></div>
        <% end %>
          </div>
          <div class="span6">
        <div class="headings">EDIT / DELETE</div>
        <%= form_tag mailing_list_maint_mailing_lists_path, method: 'get' do %>
          <p style="font-weight: bold;">To Edit/Delete an existing Mailing List entry, enter a Valid Email Address below and click the button:</p>
          <%= text_field_tag :edit_email, params[:edit_email], :minlength => 2, :maxlength => 70, placeholder: "Valid Email Address (max. 70)" %><br><br>
          <div><span valign="center"><%= submit_tag "Edit/Delete Mailing List Entry", class: "btn btn-medium btn-custom" %></span></div>
        <% end %>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Controller

def maint_mailing_list

  @page_title   = "4Dcube3Dcross Mailing List"

  if params[:commit]=='Join Our Mailing List'

    case

    when params[:list_email].blank? || params[:list_email] !~ /\A[\w+\-.]+@[\w\-.]+\.[a-z]+\z/i
      flash.now[:error] = "Email must be a valid email address. Please try again with a valid email address."
      render "maint_mailing_list"

    when MailingList.find_by(email: params[:list_email]).present?
      flash.now[:error] = "The email address entered is already on the mailing list.  Please try another email address."
      render "maint_mailing_list"

    else
      begin
        HyperCubeOfLoveMailer.add_mailing_list_email(params[:list_email]).deliver
        flash.discard[:success] = "We want to confirm that you actually requested to be added to the 4Dcube3Dcross Mailing List.  You have been sent an email with instructions on how to add yourself."
      rescue Net::SMTPFatalError, Net::SMTPSyntaxError, Net::SMTPAuthenticationError => mailing_lists_error
        logger.warn mailing_lists_error
        flash.discard[:notice] = "There was a problem with sending your email with instructions on how to add yourself.  Please try again."
      end

      redirect_to maint_mailing_list_path

    end

  else
    render "maint_mailing_list" 
  end

end  

I used flash and got the same results. I used the exact same logic but changed the redirect_to from maint_mailing_list_path to home_path just in case there could be a problem with redirecting to itself. However when I leave the home view and display another view by clicking a link then display the home view by clicking a link the message is still there.

UPDATE 1/18/2014 3:20 pm CST

application.html.erb

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <title><%= full_title(yield(:title)) %></title>
    <%= stylesheet_link_tag "application", :media => "all" %>
    <%= csrf_meta_tags %>
      <%= favicon_link_tag "/faviconhypercube.ico" %>
    <%= metamagic :description => "The 'HyperCube of Love' Puzzle from 4Dcube3DcrossTM is based on Ephesians 3:18 that tells how WIDE and LONG and HIGH and DEEP is the LOVE of CHRIST in a 4-Dimension world.", :keywords => %w(hypercube love christ jesus four-dimension 4-dimension three-dimension 3-dimension puzzle lightbe lightbecorp  cube  4dcube 3dcross cross ephesians pendant jewelry ebook app  tesseract dimension) %>
    <%= render 'layouts/shim' %>
        <script type="text/javascript">

          var _gaq = _gaq || [];
          _gaq.push(['_setAccount', 'UA-37410472-1']);
          _gaq.push(['_setDomainName', 'hypercubeoflove.com']);
          _gaq.push(['_trackPageview']);

          (function() {
            var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
            ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
            var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
          })();

        </script>
        <script type="text/javascript">

          var _gaq = _gaq || [];
          _gaq.push(['_setAccount', 'UA-46189750-1']);
          _gaq.push(['_trackPageview']);

          (function() {
            var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
            ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
            var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
          })();

        </script>
  </head>
  <body>
    <div class="container-fluid"> 
      <%= render 'layouts/header' %>
      <% flash.each do |key, value| %>
        <%= content_tag(:div, value, class: "alert alert-#{key}") %>
      <% end %>
      <%= yield %>
      <%= render 'layouts/footer' %>
    </div>
    <%= javascript_include_tag "application" %>
    <%= debug(params) if Rails.env.development? %>
  </body>
</html>
3
Looks pretty standard to me. I use the first version with redirect all the time. You'll need to post your controller code, your view code, and any changes you made by overriding Javascript. By "return to my_path" do you mean hitting the back button, and the page is not being refreshed?Beartech
Just added my controller code and view code. I'm not overriding any Javascript.Pamela Cook - LightBe Corp
Can you show the view from app/views/layouts/application.html.erb? I'm assuming this is where you are rendering the flash messages?Beartech
I have added application.html.erb.Pamela Cook - LightBe Corp

3 Answers

2
votes

Use flash.now instead of flash.

The flash variable is intended to be used before a redirect, and it persists on the resulting page for one request. This means that if we do not redirect, and instead simply render a page, the flash message will persist for two requests: it appears on the rendered page but is still waiting for a redirect (i.e., a second request), and thus the message will appears again if you click a link.

To avoid this weird behavior, when rendering rather than redirecting we use flash.now instead of flash.

The flash.now object is used for displaying flash messages on a rendered page. As per my assumption, if you ever find a random flash message where you do not expect it, you can resolve it by replacing flash with flash.now.

Hope that helps :)

0
votes

flash.discard[:symbol] = "value" doesn't do what you think it does.

Basically, that call is interpreted this way by the controller:

flash.discard[:symbol] # discards this flash. It doesn't exist yet, but it doesn't throw an exception.
flash[:symbol] = "value" # now assigns the value to the key.

So that's why both flash[:symbol] and flash.discard[:symbol] do the same thing.

As to why you're not getting a flash echo, that's a tricky one. It's possible that your rescue statement 1) first executes the flash, and then returns the flash again. Make your rescue statement return something else and see what happens?

Or rewrite your statement like this:

begin
    HyperCubeOfLoveMailer.add_mailing_list_email(params[:list_email]).deliver
    flash.discard[:success] = "We want to confirm that you actually requested to be added to the 4Dcube3Dcross Mailing List.  You have been sent an email with instructions on how to add yourself."
    redirect_to maint_mailing_list_path

rescue Net::SMTPFatalError, Net::SMTPSyntaxError, Net::SMTPAuthenticationError => mailing_lists_error
    logger.warn mailing_lists_error
    flash.discard[:notice] = "There was a problem with sending your email with instructions on how to add yourself.  Please try again."
    redirect_to maint_mailing_list_path
end
0
votes

I usually do flash messages like this:

<% flash.each do |key, value| %>
    <div class='flash' id='<%= key %>'>
      <%= value %>
    </div>
<% end %>