Problem with flashes staying on between pages

I have a login page that redirects to itself if the login is
incorrect. The browser does:

get login
post login, with wrong username and password
redirect back to login

When the post action redirects back to login it sets a flash telling
the user it failed. So far so good. The problem is that if I get
another page after that, the flash is still there. It only disapears
on the second. Here’s my integration test to do it:

class UsersTests < ActionController::IntegrationTest
#Test if the login flash stays on if we navigate to a different page
def test_login_flash
#can’t login with incorrect password
post “/user/login”, :user=> {:email => “[email protected]”,
:password => “not_correct”}
assert_response :success
assert_session_has_no :user
assert_flash_has :warning
assert_tag :div, :attributes => {:class => ‘notice’}
assert_template “user/login”

# Fetch the root and see if the flash notice is still there
get '/'
assert_response :success
assert_template "descr/index"
assert_flash_has_no :warning
assert_no_tag :div, :attributes => {:class => 'notice'}

end
end

It only fails on the last assert. The flash hash doesn’t have a notice
in it but somehow the layout is seeing one. Anyone know what this
might be?

Thanks,

Pedro.

Pedro Côrte-Real wrote:

The problem is that if I get
another page after that, the flash is still there.

Sorry, I don’t really have an answer to your question, but just to say I
had the same problem. I never did find out why it behaved this way and
ended up with a hack to work around it in the view:

<% if @flash[:notice] -%>

<%= @flash[:notice] %>
<% @flash[:notice] = nil; end -%> <%= @content_for_layout %>

you may want to use:
flash.now[:notice]

which makes the flash available to the next render, but not in the
session for the next action.

You should also access: flash[:notice] rather than @flash[:notice] as
the latter is deprecated (same as params[:id] versus @params[:id])

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

On 7/13/06, Rob B. [email protected] wrote:

you may want to use:
flash.now[:notice]

which makes the flash available to the next render, but not in the
session for the next action.

Doing this works but then my other tests fail since they’re testing if
a :notice is in the flash. They do seem to render and be fine.

So the regular flash should only be used when redirecting so that the
next request gets the flash?

I think it would make more sense for flash to live on until the next
render, wether it’s in the current action or after a redirect. So I
think I’ll use Bill’s hack.

You should also access: flash[:notice] rather than @flash[:notice] as
the latter is deprecated (same as params[:id] versus @params[:id])

Yes, i’ve been using that.

Thanks,

Pedro.

On Jul 14, 2006, at 6:40 AM, Pedro Côrte-Real wrote:

On 7/14/06, Pedro Côrte-Real [email protected] wrote:

I think it would make more sense for flash to live on until the next
render, wether it’s in the current action or after a redirect. So I
think I’ll use Bill’s hack.

This works but the flash is then empty after the first render, so I
can’t test for it in the tests. I guess I’ll have to check for the
resulting div instead.

Pedro.

Absolutely consider that your tests are just as likely to need
refactoring as any other part of your code. If you conditionally
include the

that contains the flash, then you’re testing for
the same thing.

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

On 7/14/06, Pedro Côrte-Real [email protected] wrote:

I think it would make more sense for flash to live on until the next
render, wether it’s in the current action or after a redirect. So I
think I’ll use Bill’s hack.

This works but the flash is then empty after the first render, so I
can’t test for it in the tests. I guess I’ll have to check for the
resulting div instead.

Pedro.

On 7/14/06, Rob B. [email protected] wrote:

Absolutely consider that your tests are just as likely to need
refactoring as any other part of your code. If you conditionally
include the

that contains the flash, then you’re testing for
the same thing.

Yes, sure, and I did that. The problem is that assert_tag doesn’t seem
to actually work properly. I guess my HTML isn’t XHTML enough for it.
Need to change to XHTML.

Pedro.

I have no answer here, either, but I wanted to point out that I also
had the same problem and hacked around it similar to Bill’s way below.

However, poking around just now, I see there was a bug with flash not
clearing when you are using the ActiveRecord session store. That could
be my problem, don’t know about yours.

http://www.ruby-forum.com/topic/51670#22921

Bill wrote:

Pedro Côrte-Real wrote:

The problem is that if I get
another page after that, the flash is still there.

Sorry, I don’t really have an answer to your question, but just to say I
had the same problem. I never did find out why it behaved this way and
ended up with a hack to work around it in the view:

<% if @flash[:notice] -%>

<%= @flash[:notice] %>
<% @flash[:notice] = nil; end -%> <%= @content_for_layout %>

AWDwR (1st ed.) page 340 states that: That code [from the template] runs
in an environment that gives it access to the information set up by the
controller. All instance variables of the controller ate also available
in the template.

As this is a specific exception to Ruby for Rails page 127 (“Instance
variables are only visible to the object to which they belong.”), I want
to be sure I understand correctly.

Does this means that all templates [layouts, partials, etc.], not just
the view associated with the controller, can see the instance variables
of the controller, ja?

And Helpers do not have access to instance variables, right ?

Thanks

On Jul 15, 2006, at 8:21 AM, Richard Haven wrote:

want


Posted via http://www.ruby-forum.com/.


Rails mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails

Yes all your templates that get rendered into a page, including the

layout get access to the current controller’s instance variables.
Actually after your controller action finishes running and a new
ActionView::Base opbject is created to render your template, all the
instance variables get copied over to the ActionView::Base object so
they are available to your templates. And your helpers are in the
scope of ActionView::Base as well so they also should get access to
your instance vars too i believe.

-Ezra

Hi –

On Sat, 15 Jul 2006, Richard Haven wrote:

AWDwR (1st ed.) page 340 states that: That code [from the template] runs
in an environment that gives it access to the information set up by the
controller. All instance variables of the controller ate also available
in the template.

As this is a specific exception to Ruby for Rails page 127 (“Instance
variables are only visible to the object to which they belong.”), I want
to be sure I understand correctly.

(See also Ezra’s answer.) It’s not an exception; rather, things are
engineered so that one object’s instance variables are based on those
of another object. The view object actually pulls all of the
controller’s instance variables out of a hash where they have been
stored, and assigns them to itself. Here’s the relevant method in
action_view/base.rb:

   def assign_variables_from_controller
     @assigns.each { |key, value| instance_variable_set("@#{key}", 

value) }
end

@assigns contains the controller’s instance variables. So, one by
one, the view object copies them over.

This presents the nice illusion that the action’s execution and the
template’s rendering all take place in the context of one default
object (i.e., one instance-variable owner), but under the hood that
isn’t the case.

David


http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
http://www.manning.com/black => RUBY FOR RAILS (reviewed on
Slashdot, 7/12/2006!)
http://dablog.rubypal.com => D[avid ]A[. ]B[lack’s][ Web]log
[email protected] => me

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs