Jump to content

The ultimate community for Ruby on Rails developers.


Photo

Rails flash notice won't go away in Safari?

flash sessions safari

  • Please log in to reply
42 replies to this topic

#1 joshukraine

joshukraine

    Signalman

  • Members
  • 20 posts

Posted 11 December 2013 - 10:27 AM

I have a Rails 3.2 app that manages students. It has a fairly typical nav bar across the top (Foundation 5) which contains a quick search field. The nav bar is displayed on every page of the site.

If you enter a valid (numeric) student ID into the search field, you simply jump to that student's page. If you enter text or other non-numeric input, you get a flash error asking for valid input. If you enter an id that's not found, you get a flash notice saying it wasn't found. In either of the latter two cases, the controller should just drop you back to whatever page you came from and display the appropriate flash message.

For starters, here's the search field in the view:

<%= form_tag search_students_path, method: 'get' do %>
<div id="nav-search" class="row collapse">
  <div id="nav-search-field" class="small-21 columns">
    <%= text_field_tag :search, nil, autocomplete: 'off' %>
  </div>
  <div id="nav-search-icon" class="small-3 columns">
    <%= submit_tag '&#xf002;'.html_safe, class: 'button fa fa-search spin', name: 'submit' %>
  </div>
</div>
<% end %>

And here's the controller action:

def search
  session[:return_to] ||= request.referer
  if params[:search].to_i.zero?
    flash[:error] = %Q[<i class="fa fa-times fa-fw"></i> Please enter a numeric student ID.].html_safe
    redirect_to session.delete(:return_to)
  else
    id = params[:search].to_i.abs
    @student = Student.search(id).first
    if @student
      redirect_to @student
    else
      flash[:caution] = %Q[<i class="fa fa-warning fa-fw"></i> Sorry, we couldn't find a student with ID #{id}.].html_safe
      redirect_to session.delete(:return_to)
    end
  end
end

Lastly, here's the code for rendering flash messages in application.html.erb:

<% flash.each do |key, value| %>
  <div data-alert class="alert-box cbc-<%= key %>">
    <%= value %>
    <a href="#" class="close">&times;</a>
  </div>
<% end %>

In Chrome and FireFox this works exactly as expected. The flash appears for one request, then disappears. However, in Safari, once the flash comes up it never goes away for that page. So if you get the error flash on the home page, for example, you can refresh all you want. It stays put. You can go to another page, and then come back, and it's still there. The same is true for other pages. Once the flash message has appeared on a given page, it doesn't go away.

 

Thus my question: how can I get Safari to clear the flash after the first request?

 

I'm aware of the whole "flash vs. flash.now" issue when rendering pages. But even then, the flash will disappear if you simply refresh. I actually tried flash.now in this case, but then the flash isn't displayed at all in any browser.

Since this appears to be a browser-specific problem, here are some further stats on my system:

  • Mac OS X 10.9
  • Safari 7.0
  • Rails 3.2.16

One final observation. After playing around with this issue in Safari, I noticed that if I clicked my bookmark for http://localhost:3000/, that would clear the flash. Of course, all the navigation links in my site layout contain relative paths, whereas the bookmark is calling a full url.

Anyway, hope that made sense. Thanks in advance for your help!



#2 james

james

    Guard

  • Moderators
  • 221 posts
  • LocationLeeds, U.K.

Posted 11 December 2013 - 12:53 PM

flash is effectively an alias for session. Unless you clear the flash messages they will be forever there or until a new session is started, cookies deleted.

You don't show anywhere in your code where you clear the flash I would expect to see something like

flash[:caution] = nil 

somewhere in your code.

 

This is not a browser specific issue. You need to define the condition that clears the flash content as above and place it wherever you feel it is appropriate to do so which is not as easy as it may at first sound.


Programming is just about problem solving!


#3 joshukraine

joshukraine

    Signalman

  • Members
  • 20 posts

Posted 11 December 2013 - 01:34 PM

Hi James,

 

Thanks for the reply. I'm fairly new to Rails, so perhaps you could help me understand a couple of points more clearly here. 

 

Firstly, why do flash messages normally clear on their own after one request without explicitly expressing this in the code? Obviously my implementation of the search feature is different in some way, but I'm not seeing why the flash doesn't clear itself in this case when it does so in every other implementation in the app.

 

Secondly, I've actually tried code similar to what you suggested (e.g. flash = nil) and I've placed it in my site layout file like so:

<% flash.each do |key, value| %>
  <div data-alert class="alert-box cbc-<%= key %>">
    <%= value %>
    <a href="#" class="close">&times;</a>
  </div>
<% end %>
<% flash = nil %>

This doesn't seem to work though. You mentioned placing it conditionally. Could you offer an example of how that might look?

 

In case it would help, here are a few gists that contain more code from the app in question:

As you can see in students controller, I display flash messages all the time in various actions. All these flash messages are displayed through the same code in the app layout file, and they all disappear after the first request except the flash in the search action.

 

If there's more info I can provide that would make the issue clearer, I'd be happy to do so. Just let me know. Thanks again for your help!

 

Josh



#4 james

james

    Guard

  • Moderators
  • 221 posts
  • LocationLeeds, U.K.

Posted 11 December 2013 - 01:59 PM

Firstly, why do flash messages normally clear on their own after one request without explicitly expressing this in the code?

 

 

They don't! They stick around for as long as the session sticks around, you may well have something in your normal browser that clears out cookies on a regular basis which may explain why you are seeing a difference.

 

Obviously my implementation of the search feature is different in some way, but I'm not seeing why the flash doesn't clear itself in this case when it does so in every other implementation in the app.

 

 

Rather than try to clear the flash at an appropriate time, if you really want a one off flash message then you could use flash.now

 

so instead of

flash[:caution] = %Q[<i class="fa fa-warning fa-fw"></i> Sorry, we couldn't find a student with ID #{id}.].html_safe
redirect_to session.delete(:return_to)

you would have

flash.now[:caution] = %Q[<i class="fa fa-warning fa-fw"></i> Sorry, we couldn't find a student with ID #{id}.].html_safe
redirect_to session.delete(:return_to)

Which would solve your problem


Programming is just about problem solving!


#5 james

james

    Guard

  • Moderators
  • 221 posts
  • LocationLeeds, U.K.

Posted 11 December 2013 - 02:03 PM

Sorry, I missed your bit about flash.now.

 

It's just a case of knowing where and at what time to clear the flash message.

 

On a full page refresh the same controller and action should be called so the same checks should be run and therefore the same flash message should be displayed. Not sure why that is not happening.

 

If you go down the route of flash.now make sure the above is happening. If you want to clear the flash message that should be done at the controller level.

 

Or perhaps provide a specific key for this one scenario e.g. flash[:search_caution] and reflect that change in the template that way it won't interfere with other pages and you can clear the flash message as the first line of the relevant action. Should do the trick


Programming is just about problem solving!


#6 james

james

    Guard

  • Moderators
  • 221 posts
  • LocationLeeds, U.K.

Posted 11 December 2013 - 03:40 PM

so try this

def search
  flash[:caution] = nil
  session[:return_to] ||= request.referer
  if params[:search].to_i.zero?
    flash[:error] = %Q[<i class="fa fa-times fa-fw"></i> Please enter a numeric student ID.].html_safe
    redirect_to session.delete(:return_to)
  else
    id = params[:search].to_i.abs
    @student = Student.search(id).first
    if @student
      redirect_to @student
    else
      flash[:caution] = %Q[<i class="fa fa-warning fa-fw"></i> Sorry, we couldn't find a student with ID #{id}.].html_safe
      redirect_to session.delete(:return_to)
    end
  end
end

Programming is just about problem solving!


#7 joshukraine

joshukraine

    Signalman

  • Members
  • 20 posts

Posted 11 December 2013 - 03:53 PM

Thanks for all the info. I tried your most recent suggestion but it didn't change anything. The flash works normally in both Chrome and Firefox - that is, it disappears after one request - but in Safari the flash message continues to appear regardless of the number of times the page is refreshed.



#8 james

james

    Guard

  • Moderators
  • 221 posts
  • LocationLeeds, U.K.

Posted 11 December 2013 - 03:59 PM

Show me the develpment.log output for the refresh in safari. What you think is happening is probably not what is actually happening. The log file entries will show what the reality is. Also watch your log output as you hit refresh to make sure that something is actually happening.


Programming is just about problem solving!


#9 joshukraine

joshukraine

    Signalman

  • Members
  • 20 posts

Posted 11 December 2013 - 04:25 PM

OK here's the log output. The full output is littered with tons of GET requests which are loading js and css assets like this:

 

Started GET "/assets/lessons.js?body=1" for 127.0.0.1 at 2013-12-11 18:19:08 +0200
Served asset /lessons.js - 304 Not Modified (0ms)
I'm fairly sure that those are not relevant here, so I've omitted them for brevity. That said, here's the log minus the asset requests: (comments mine)
 
# Vist the home page at http://localhost:3000/
Started GET "/" for 127.0.0.1 at 2013-12-11 18:15:34 +0200
Processing by PagesController#home as HTML
  Coach Load (0.3ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
  Rendered pages/home.html.erb within layouts/application (0.1ms)
  Rendered layouts/_top-nav.html.erb (1.9ms)
  Rendered layouts/_sidenav.html.erb (1.0ms)
Completed 200 OK in 18.5ms (Views: 17.0ms | ActiveRecord: 0.3ms)

# Submit the search form with no input
Started GET "/students/search?utf8=%E2%9C%93&search=&submit=%EF%80%82" for 127.0.0.1 at 2013-12-11 18:16:12 +0200
Processing by StudentsController#search as HTML
  Parameters: {"utf8"=>"✓", "search"=>"", "submit"=>"?"}
  Coach Load (0.5ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
Redirected to http://localhost:3000/
Completed 302 Found in 2.8ms (ActiveRecord: 0.5ms)

# Get redirected back to the homepage
Started GET "/" for 127.0.0.1 at 2013-12-11 18:16:12 +0200
Processing by PagesController#home as HTML
  Coach Load (0.4ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
  Rendered pages/home.html.erb within layouts/application (0.1ms)
  Rendered layouts/_top-nav.html.erb (1.8ms)
  Rendered layouts/_sidenav.html.erb (0.9ms)
Completed 200 OK in 21.1ms (Views: 19.5ms | ActiveRecord: 0.4ms)

# Click the link for the homepage again, flash still appears here.
Started GET "/" for 127.0.0.1 at 2013-12-11 18:16:50 +0200
Processing by PagesController#home as HTML
  Coach Load (0.4ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
  Rendered pages/home.html.erb within layouts/application (0.1ms)
  Rendered layouts/_top-nav.html.erb (1.8ms)
  Rendered layouts/_sidenav.html.erb (1.0ms)
Completed 200 OK in 19.4ms (Views: 17.6ms | ActiveRecord: 0.4ms)

Also, the more I've played with this in Safari, the more I've noticed odd behavior. For example, occasionally the flash message does disappear. But then I can come right back and repeat the process and it will stick. Other times I refresh the page by clicking a nav link to that page and the flash sticks, but then when I hit the refresh button in browser, I just get a completely blank page. Very weird.

 

Anyway, thanks for helping!



#10 james

james

    Guard

  • Moderators
  • 221 posts
  • LocationLeeds, U.K.

Posted 11 December 2013 - 05:28 PM

Picking up on the log output.

 

You have two different controller actions in play here

# Submit the search form with no input
Started GET "/students/search?utf8=%E2%9C%93&search=&submit=%EF%80%82" for 127.0.0.1 at 2013-12-11 18:16:12 +0200
Processing by StudentsController#search as HTML
Parameters: {"utf8"=>"✓", "search"=>"", "submit"=>"?"}
Coach Load (0.5ms) SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
Redirected to http://localhost:3000/
Completed 302 Found in 2.8ms (ActiveRecord: 0.5ms)
# Get redirected back to the homepage
Started GET "/" for 127.0.0.1 at 2013-12-11 18:16:12 +0200
Processing by PagesController#home as HTML
Coach Load (0.4ms) SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
Rendered pages/home.html.erb within layouts/application (0.1ms)
Rendered layouts/_top-nav.html.erb (1.8ms)
Rendered layouts/_sidenav.html.erb (0.9ms)
Completed 200 OK in 21.1ms (Views: 19.5ms | ActiveRecord: 0.4ms)

One is going to the pages controller home action and the other is going to the students controller search action

 

Which one is giving you the problem? You need to take very careful note of what happens in the log file for when it works vs when it doesn't work


Programming is just about problem solving!


#11 joshukraine

joshukraine

    Signalman

  • Members
  • 20 posts

Posted 11 December 2013 - 05:41 PM

Yes, I noticed that as well. The search action is in the students controller, but since the nav bar appears on every page, the redirect could send the user back anywhere. Interestingly enough, even when I run the search from a page that is governed by the students controller (say for example, students#new) the same problem occurs. So to answer your question, the "problem controller" could potentially be any in the site.

 

In an attempt to better illustrate what's going on, I decided to make a quick screen recording which demonstrates the behavior. You can view that video on YouTube. It's about 5 minutes. Towards the end of the video, I demonstrate submitting the form in Safari from /students/new.

 

I'd love to hear your thoughts. Meanwhile, I'll try to do some log checking and see if I can come up with anything.

 

Oh, and one other thought here. It seems that a universal search bar would be a fairly common feature in many sites. (I noticed that the RailsForum site has one as well.) Perhaps I'm approaching it wrong? If there's some best practice for this that I'm missing, I'd love to know. I've implemented it as best I know how, but if there's a better way, I'm certainly open to that.



#12 james

james

    Guard

  • Moderators
  • 221 posts
  • LocationLeeds, U.K.

Posted 11 December 2013 - 07:07 PM

Hhhmm!

A quick and dirty solution would be to provide a before_action filter in the application controller to set the flash[:caution] = nil.

 

That doesn't answer the "Why is it happening?" question though, I'm wondering what would happen if you changed to to flash[:error] or flash[:notice]. It could be that rails "magic" is happening for specific key's

 

So 3 things to try.

 

1) Check the log file entries for what happens when you hit the browser refresh button and nothing get's rendered.

That should give some indication as to what is happening to cause the blank page issue

 

2) Change the flash[:caution] to a flash[:error] or some other key that you get the expected behaviour for and see if the problem goes away.

If so then you can be pretty confident that the solution is to switch back to the caution key and rest in a before_action filter in the application controller.

 

3) Implement the before action filter as described above to see if that resolves your issue.

 

I have a suspicion that javascript may be the underlying problem here but I can;t think why that would be.


Programming is just about problem solving!


#13 joshukraine

joshukraine

    Signalman

  • Members
  • 20 posts

Posted 11 December 2013 - 07:52 PM

OK I tried the before_filter idea, defined in the application controller:

def flash_to_nil
  flash[:caution] = nil
end

However, in theory I'd have to call that at the top of every controller. So for testing, I just called it in the students and pages controllers. But all it does is to simply display an empty flash notice (colored frame, no text) on every page. And that happens in every browser.

 

Also wanted to point out that the search action uses flash[:caution] and also flash[:error] depending on what you put in the form. The former is for an id that doesn't exist while the latter is for non-numeric input. Both produce the same flash-sticking behavior. I doubt that these are causing a namespace crash in Rails because I use those same flash keys across the whole app, along with flash[:success] and flash[:info]. The only problem is in the search action, and then only in Safari.

 

So getting back to the log, your suggestion to check the output on a blank refresh turned up something interesting. The reason nothing displays is because when I refresh, no assets are loaded. It loads the page and then just dies. So to test this, I quit Safari completely, then opened it back up. Then I went through several steps in the app, submitting various things and checking the log each time. Bear in mind that I've not been posting the assets output for brevity, but at the end, the assets actually did not appear at all. Anyway, here's the output with my comments:

# Launch Safari after quit. Visit localhost:3000
Started GET "/" for 127.0.0.1 at 2013-12-11 21:19:48 +0200
Processing by PagesController#home as HTML
  Coach Load (0.4ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
  Rendered pages/home.html.erb within layouts/application (0.1ms)
  Rendered layouts/_top-nav.html.erb (2.9ms)
  Rendered layouts/_sidenav.html.erb (1.0ms)
Completed 200 OK in 25.6ms (Views: 23.6ms | ActiveRecord: 0.4ms)

# Submit empty search
Started GET "/students/search?utf8=%E2%9C%93&search=&submit=%EF%80%82" for 127.0.0.1 at 2013-12-11 21:20:13 +0200
Processing by StudentsController#search as HTML
  Parameters: {"utf8"=>"✓", "search"=>"", "submit"=>"?"}
  Coach Load (0.5ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
Redirected to http://localhost:3000/
Completed 302 Found in 2.4ms (ActiveRecord: 0.5ms)

# Get redirected and see error - flash[:error]
Started GET "/" for 127.0.0.1 at 2013-12-11 21:20:13 +0200
Processing by PagesController#home as HTML
  Coach Load (0.3ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
  Rendered pages/home.html.erb within layouts/application (0.0ms)
  Rendered layouts/_top-nav.html.erb (2.0ms)
  Rendered layouts/_sidenav.html.erb (0.8ms)
Completed 200 OK in 18.7ms (Views: 17.0ms | ActiveRecord: 0.3ms)

# Browser refresh - screen reappears normally and NO STICKING FLASH!
Started GET "/" for 127.0.0.1 at 2013-12-11 21:20:29 +0200
Processing by PagesController#home as HTML
  Coach Load (0.7ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
  Rendered pages/home.html.erb within layouts/application (0.1ms)
  Rendered layouts/_top-nav.html.erb (1.9ms)
  Rendered layouts/_sidenav.html.erb (0.8ms)
Completed 200 OK in 65.7ms (Views: 63.3ms | ActiveRecord: 0.7ms)

# Submit empty search again...
Started GET "/students/search?utf8=%E2%9C%93&search=&submit=%EF%80%82" for 127.0.0.1 at 2013-12-11 21:22:32 +0200
Processing by StudentsController#search as HTML
  Parameters: {"utf8"=>"✓", "search"=>"", "submit"=>"?"}
  Coach Load (0.4ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
Redirected to http://localhost:3000/
Completed 302 Found in 2.2ms (ActiveRecord: 0.4ms)

# No flash at all. :/
Started GET "/" for 127.0.0.1 at 2013-12-11 21:22:32 +0200
Processing by PagesController#home as HTML
  Coach Load (0.3ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
  Rendered pages/home.html.erb within layouts/application (0.0ms)
  Rendered layouts/_top-nav.html.erb (1.7ms)
  Rendered layouts/_sidenav.html.erb (0.8ms)
Completed 200 OK in 20.3ms (Views: 18.6ms | ActiveRecord: 0.3ms)


# Submit junk to form.
Started GET "/students/search?utf8=%E2%9C%93&search=asfadsf&submit=%EF%80%82" for 127.0.0.1 at 2013-12-11 21:24:53 +0200
Processing by StudentsController#search as HTML
  Parameters: {"utf8"=>"✓", "search"=>"asfadsf", "submit"=>"?"}
  Coach Load (0.4ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
Redirected to http://localhost:3000/
Completed 302 Found in 2.2ms (ActiveRecord: 0.4ms)

# Redirected, flash appears
Started GET "/" for 127.0.0.1 at 2013-12-11 21:24:53 +0200
Processing by PagesController#home as HTML
  Coach Load (0.3ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
  Rendered pages/home.html.erb within layouts/application (0.0ms)
  Rendered layouts/_top-nav.html.erb (1.7ms)
  Rendered layouts/_sidenav.html.erb (0.8ms)
Completed 200 OK in 18.0ms (Views: 16.1ms | ActiveRecord: 0.3ms)

# Go back to home page, flash sticking again.
Started GET "/" for 127.0.0.1 at 2013-12-11 21:25:00 +0200
Processing by PagesController#home as HTML
  Coach Load (0.4ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
  Rendered pages/home.html.erb within layouts/application (0.1ms)
  Rendered layouts/_top-nav.html.erb (3.4ms)
  Rendered layouts/_sidenav.html.erb (0.9ms)
Completed 200 OK in 27.3ms (Views: 25.1ms | ActiveRecord: 0.4ms)

# Click home link multiple times, flash stays.
...

# Refresh from browser - blank screen. Assets not loading!
Started GET "/" for 127.0.0.1 at 2013-12-11 21:27:01 +0200
Processing by PagesController#home as HTML
  Coach Load (0.6ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
  Rendered pages/home.html.erb within layouts/application (0.1ms)
  Rendered layouts/_top-nav.html.erb (2.0ms)
  Rendered layouts/_sidenav.html.erb (0.8ms)
Completed 200 OK in 69.5ms (Views: 67.1ms | ActiveRecord: 0.6ms)

# Refresh again, still no assets.
Started GET "/" for 127.0.0.1 at 2013-12-11 21:27:18 +0200
Processing by PagesController#home as HTML
  Coach Load (0.5ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
  Rendered pages/home.html.erb within layouts/application (0.1ms)
  Rendered layouts/_top-nav.html.erb (1.8ms)
  Rendered layouts/_sidenav.html.erb (0.8ms)
Completed 200 OK in 19.0ms (Views: 16.8ms | ActiveRecord: 0.5ms)

# Click localhost:3000 bookmark, assets reload just fine.
Started GET "/" for 127.0.0.1 at 2013-12-11 21:29:26 +0200
Processing by PagesController#home as HTML
  Coach Load (0.3ms)  SELECT "coaches".* FROM "coaches" WHERE "coaches"."remember_token" = 'MgfSFnRUwCuD9vKoDp6r3A' ORDER BY coaches.created_at ASC LIMIT 1
  Rendered pages/home.html.erb within layouts/application (0.1ms)
  Rendered layouts/_top-nav.html.erb (1.9ms)
  Rendered layouts/_sidenav.html.erb (0.8ms)
Completed 200 OK in 19.1ms (Views: 17.4ms | ActiveRecord: 0.3ms)


Started GET "/assets/application.css?body=1" for 127.0.0.1 at 2013-12-11 21:29:26 +0200
Served asset /application.css - 304 Not Modified (2ms)


Started GET "/assets/font-awesome.css?body=1" for 127.0.0.1 at 2013-12-11 21:29:26 +0200
Served asset /font-awesome.css - 304 Not Modified (0ms)


Started GET "/assets/comments.css?body=1" for 127.0.0.1 at 2013-12-11 21:29:26 +0200
Served asset /comments.css - 200 OK (0ms)
.
.
.

So this brings me to a new thought. I wonder if the culprit here could be Foundation. I am using Foundation 5 for my front-end framework and it's still pretty new. In particular, the Foundation gem (foundation-rails) is very new. I've already had trouble deploying to Heroku because of the way that Foundation handles assets. Do you suppose that the problem could have something to do with an incompatibility between Foundation and Safari? If so, that might explain why the behavior only occurs in Safari.

 

Thanks again for your time here. Much appreciated!



#14 james

james

    Guard

  • Moderators
  • 221 posts
  • LocationLeeds, U.K.

Posted 11 December 2013 - 08:23 PM

Yes regarding foundation. It could well be your problem.

I hate using gems, I know Rails itself is a set of gems, but use of non core, with a few exceptions, gems are a big no for me.

 

OK I tried the before_filter idea, defined in the application controller:

def flash_to_nil
flash
[:caution] = nil
end

However, in theory I'd have to call that at the top of every controller. So for testing, I just called it in the students and pages controllers. But all it does is to simply display an empty flash notice (colored frame, no text) on every page. And that happens in every browser.

 

 

 

I think you are misunderstanding this.

In the application_controller.rb file define a

 

This can go somewhere near the top of the file but after the class definition.

before_action :clear_flash

Then in a private section at the bottom of the application_controller you want

private
def clear_flash
  flash[:caution] = nil
end

Anything that appears after the word private will not be visible to other controllers. It's not a block it's a position thing, one of the very few things Rails developers got wrong IMO. Anyway, just something to be aware of rather than worry about.

 

All controllers ultimately descend from application_controller so all actions will call the clear flash message automatically by adding this code in the application controller. OO rocks :)

 

Try it and see if it works for you


Programming is just about problem solving!


#15 joshukraine

joshukraine

    Signalman

  • Members
  • 20 posts

Posted 11 December 2013 - 08:32 PM

Ah I see. Yes, I misunderstood what you meant. OK, so I added the before filter to the top of application_controller.rb, then defined it in the private section as you said. But the effect is the same: I get an empty caution flash appearing on every page regardless. Same in Chrome and Safari. If I submit bad data to a form, I also get the flash for that in addition to the empty caution flash.

 

Well, I'll follow up a bit on the Foundation idea. They have their own forum so I might try asking over there and see if I can turn up anything.

At any rate, thanks a million for your help. If I get this solved, I'll be sure to come back here and post the answer. :) Cheers!



#16 james

james

    Guard

  • Moderators
  • 221 posts
  • LocationLeeds, U.K.

Posted 11 December 2013 - 08:42 PM

OK, looking at your template, you have

<% flash.each do |key, value| %>
  <div data-alert class="alert-box cbc-<%= key %>">
    <%= value %>
    <a href="#" class="close">&times;</a>
  </div>
<% end %>

So if the key exists bu there is no value then you are displaying the box, you just need to add a check to ensure there is a value before displaying it.

<% flash.each do |key, value| %>
  <% if value.present? %>
    <div data-alert class="alert-box cbc-<%= key %>">
      <%= value %>
      <a href="#" class="close">&times;</a>
    </div>
  <%end%>
<% end %>

That should solve your flash message issues

 

As far as the assets thing is concerned and the blank pages, it may be worth googling that to see what comes up


Programming is just about problem solving!


#17 joshukraine

joshukraine

    Signalman

  • Members
  • 20 posts

Posted 11 December 2013 - 08:51 PM

OK, did that. But now flash[:caution] messages do not appear at all anywhere. Which to me makes sense because aren't we killing them before they ever get off the ground? It would seem that our application_controller is intercepting any flash[:caution] value that gets sent down the pipe and setting it to nil before it gets displayed.



#18 james

james

    Guard

  • Moderators
  • 221 posts
  • LocationLeeds, U.K.

Posted 11 December 2013 - 09:20 PM

Sorry, you are right.

 

The process should work like this

 

An action is called from the browser by clicking a link or pressing a button, in the case of the search button this will call the search action in the students controller right?

 

So before the action is called the flash[:caution] value will be cleared by the before action filter.

Then the search code is run

def search
  session[:return_to] ||= request.referer
  if params[:search].to_i.zero?
    flash[:error] = %Q[<i class="fa fa-times fa-fw"></i> Please enter a numeric student ID.].html_safe
    redirect_to session.delete(:return_to)
  else
    id = params[:search].to_i.abs
    @student = Student.search(id).first
    if @student
      redirect_to @student
    else
      flash[:caution] = %Q[<i class="fa fa-warning fa-fw"></i> Sorry, we couldn't find a student with ID #{id}.].html_safe
      redirect_to session.delete(:return_to)
    end
  end
end

So the flash[:caution] message is set and then a re-direct is called to a different action (the referrer.

The different action causes the flash message to be cleared by the before action filter.

 

This is also why flash.now is not working for you either.

 

You need to retain the flash message across a single redirect and then clear it.

 

Possibly a simple solution is to maintain a counter.

In the before action check if the value exists for caution. If it exists add 1 to a counter held in a session variable initialised to 0.

Then check the value of the counter, if it is > 1 clear the caution message and reset the counter to 0. Job done.

 

There is most likely a more elegant way of achieving this but it's late and I can;t think of a better solution off the top of my head.

 

Once again. Sorry, I should have spotted that straight away


Programming is just about problem solving!


#19 james

james

    Guard

  • Moderators
  • 221 posts
  • LocationLeeds, U.K.

Posted 12 December 2013 - 09:54 AM

Having read up a bit more on flash messaging I have discovered that the flash is cleared after the next redirect. so tjhe code I gave you is actually just a duplicate of what Rails does anyway, so I waas wrong when I said the flash stays around until it is cleared. It's behaviour is different to the session class.

 

So something is keeping it around when it shouldn't be and I can only guess that this will be some gem or code that you have written that overrides something to do with the hash class but that doesn;t explain this special case.

 

You have me stumped.

 

To isolate the issue it might be worth making a copy of the project, or making a new git branch of you current project, remove all the gems and then add them back in one by one until the problem starts ocurring. Or turn that on it's head, remove the most likely cuplrit one by one until the problem goes away.

 

Otherwise you have the option I gave you in my previous answer, which is less than satisfactory, whatever is causing this may have knock on effects and fixing symptoms such as I have suggested you do, is never really a good idea.


Programming is just about problem solving!


#20 joshukraine

joshukraine

    Signalman

  • Members
  • 20 posts

Posted 12 December 2013 - 10:28 AM

Thanks for the info. I agree this seems like something having to do with gems (Foundation?) and I think that sounds like a good path to start on. I'll create a new topic branch for this and see what I come up with. As I said before, if/when I find the solution, I'll be sure to post back here.







Also tagged with one or more of these keywords: flash, sessions, safari

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users