Variables output in views/layouts?

Hi, I usually always deal with arrays this is the first time I have to deal with a regular variable on a different view in this case in the layout.. so I have in my method:   def online          @online = Status.count_by_sql "SELECT COUNT(*) FROM status WHERE status = 'online';"   end

and in my layout view I have <%= @online %>

and nothing comes up... :frowning:

What im doing wrong?

my question is how can I call variables from different controllers on different views or in my layouts...??

Thanks

maybe the count is zero? Have you tried printing the value to the log? try logger.info("value of count: #{@count}") in your controller code

and if you're trying to display the number of users online, you might want to look at the session data to figure this out.

Mike Garey wrote:

maybe the count is zero? Have you tried printing the value to the log? try logger.info("value of count: #{@count}") in your controller code

and if you're trying to display the number of users online, you might want to look at the session data to figure this out.

Yes I have try this testing it with the view for that method.. and no this is not for the users online but another application. I also have try it from the console and there works..

so I am puzzle I am searching google with no straight result.. searching for "rails instance variables in layout"

I get a lot of how to use your view variables in layouts and viceversa but not the method variables or instance variables

if the @online variable contains a value, it will be printed by the <%= @online %> statement. If nothing is printed, then the variable contains a null value. What gets printed in your log? Try logging the value in your view code right before you use the <%= @online %>, such as the following:

<% logger.info("online contains #{@online} online.blank? #{@online.blank?}") %> <%= @online %>

if the logger prints out a value for @online, yet the second statement prints nothing, then something is seriously wrong with your rails stack

Ok I added that and I get:

Ok I added that and I get: ----------------------------- Rendering pages/show online contains online.blank? true Rendered layouts/_menu (0.00793) ------------------------------------------ it returns true..

do you understand that returning true is not what you want? The line of code I wrote was:

<% logger.info("online contains #{@online} online.blank? #{@online.blank?}") %>

this prints the value of the @online ivar and it also prints whether or not @online is nil or blank (if it's an empty string). In this case it printed "true", which means that @online doesn't contain what you think it contains. Most likely it's nil.

I know it has a value because if I go to http://url.com/status/whos_online I get the right ammount of users online..

and what does your whos_online method do?

not if I put exacly the same variable in the layout is not showing anything..

the @online method will only be assigned in your 'online' action. If you put:

Number of users online: <%= @online %> in your layout, then this will only contain a value if the action you're calling assigns to the @online variable. Since you're displaying this value in your layout, you'll want to globally assign this value either in a before filter in your controller, or in your ApplicationController.

Mike Garey escribió:

do you understand that returning true is not what you want? The line of code I wrote was:

<% logger.info("online contains #{@online} online.blank? #{@online.blank?}") %>

this prints the value of the @online ivar and it also prints whether or not @online is nil or blank (if it's an empty string). In this case it printed "true", which means that @online doesn't contain what you think it contains. Most likely it's nil.

Yes, of course, this is why I sent the console output :slight_smile: so the issue is that layout is seen the variable as nil.

and what does your whos_online method do?

is the method were I create the variable @online

class StatusController < ApplicationController def who_online         @online = Status.count_by_sql "SELECT COUNT(*) FROM status WHERE status = 'online';" end end

the @online method will only be assigned in your 'online' action. If you put:

Number of users online: <%= @online %> in your layout, then this will only contain a value if the action you're calling assigns to the @online variable. Since you're displaying this value in your layout, you'll want to globally assign this value either in a before filter in your controller, or in your ApplicationController.

Hmm I'm confused.. I though that the application layout will be used if there is no default layout for a method, and that instances variables from methods can be used in their layouts.. this is why I was hoping for this to work.

Basically the layout Im using already has data that works well with a render of _menu etc.. I am just trying to add to a corner of my site the amount of people using the service.. so how will I go to do this? I though this was going to be easy.. :frowning:

Thanks.

Hmm I'm confused.. I though that the application layout will be used if there is no default layout for a method, and that instances variables from methods can be used in their layouts.. this is why I was hoping for this to work.

You are right about the layout. The problem is that the @online is not being set with every method that uses the application layout. The purist way to solve the problem would be to create a before_filter in the ApplicationController and use that filter to load the @online instance variable. That way it will be inherited by all your controllers and available to all your actions when they default into using the application layout.

You might also want to wrap up your lookup into a class method on the Status controller. It will make things more expressive when you re- read the code later.

class Status < ARec::Base ...   def self.currently_online     count(:conditions=>{:status=>'online'})   end ... end

If you can deal with a little impurity (mixing V/C) in your application layout you can also put the call to find the count in your template:

<%= Status.currently_online %>

You are right about the layout. The problem is that the @online is not being set with every method that uses the application layout. The purist way to solve the problem would be to create a before_filter in the ApplicationController and use that filter to load the @online instance variable. That way it will be inherited by all your controllers and available to all your actions when they default into using the application layout.

You might also want to wrap up your lookup into a class method on the Status controller. It will make things more expressive when you re- read the code later.

class Status < ARec::Base ...   def self.currently_online     count(:conditions=>{:status=>'online'})   end ... end

If you can deal with a little impurity (mixing V/C) in your application layout you can also put the call to find the count in your template:

Hi, I have ended moving the method to the application controller. Thanks!