Topic: Global var for use in controllers and views?

Where can I put an array so it can be used from all my controllers and views?

SERVICE_TYPE = ['public', 'commerical']

I tried putting it in application.rb but it does not appear to be extend to views?

I also tried @SERVICE_TYPE.

Many thanks, AFM.

Re: Global var for use in controllers and views?

I use environment.rb, but I'm not sure if that's the "standard" approach.

You could also add it to a model object, and reference it like Service.SERVICE_TYPES.

Last edited by thabenksta (2006-06-27 10:05:52)

Re: Global var for use in controllers and views?

You might try setting it up as a session variable in your application.rb file.

app/controllers/application.rb

class ApplicationController < ActionController::Base
  def create_default_variables
    session[:service_type] = %w{ public commericial }
  end
end

app/controllers/your_controller.rb
class YourController < ActionController::Base
  before_filter :create_default_variables
end

Hope that helps.

Most code examples are usually pulled out of the air and not tested. Use at your own risk!

Re: Global var for use in controllers and views?

Be careful about session variables for global storage because they don't scale particularly well. If your site gets much traffic, you can multiply the 10 bytes or so for this variable by the number of unexpired sessions and you start seeing a potential performance problem.

Also, Rails hasn't historically garbage collected session cookies, so you could have a boatload of those laying around on your server.

environment.rb is a great place for truly global variables.

Just a thought.

Re: Global var for use in controllers and views?

This is the thing, I tried putting it in application.rb but could not use it in the views, let me show you:

class ApplicationController < ActionController::Base
  @SERVICE_TYPES = ['bus', 'coach']
  # ^ views can not see this??
end

In a view:

<%= @SERVICE_TYPES[1] %>

Error:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occured while evaluating nil.[]


Can you spot the mistake or give me a working example?

Many thanks, AFM.

Last edited by afm (2006-06-28 05:26:23)

Re: Global var for use in controllers and views?

I wasn't thinking about scaling, that's for the tip cwd. I realized looking at this problem today that you are attempting to pass this variable off as an instance variable. Try this:

app/application.rb

class ApplicationController < ActionController::Base
  $SERVICE_TYPES = %w{ public commercial }
end

app/test_controller.rb
class TestController < ApplicationController
  def index
    logger.info "Service Types Equal: " + $SERVICE_TYPES.join(' and ')
  end
end

app/views/test/index.rhtml
<%= debug $SERVICE_TYPES %>

Produces:
---
- public
- commercial

log/development.log

Processing TestController#index (for 127.0.0.1 at 2006-06-28 09:02:17) [GET]
  Session ID: 9bce7eccb192b544c88104867d3adb86
  Parameters: {"action"=>"index", "controller"=>"test"}
Service Types Equal: public and commercial
Rendering test/index

So to recap: variables that start with @ are instance variables, variables that do not have a prefix are local variables, variables that start with @@ are class variables, variables that start with $ are global and lastly constants are in ALL_CAPS.

Last edited by Reedy (2006-06-28 10:14:08)

Most code examples are usually pulled out of the air and not tested. Use at your own risk!

Re: Global var for use in controllers and views?

Should learn to type faster, that pretty much covers it I guess ^_^

Last edited by marsvin (2006-06-28 10:54:29)

Re: Global var for use in controllers and views?

Merci bocue!

To get an drop down box from the array I used:

<select id="search_service_type" name="search[service_type]">
  <% $SERVICE_TYPES.length.times do |ctr| %>
    <option value="<%= ctr.to_s %>"><%= $SERVICE_TYPES[ctr] %></option>
  <% end %>
</select>

Last edited by afm (2006-07-04 08:42:40)

Re: Global var for use in controllers and views?

Reedy wrote:

class ApplicationController < ActionController::Base
  $SERVICE_TYPES = %w{ public commercial }
end

Global variables don't work well with Rails because they aren't shared across multiple FastCGI instances. Therefore, if one instance changes the variable, the other instance will not show the change. If you don't plan on changing the global variable, then best to use a constant.

# put this outside your class definition so it applies to everything
SERVICE_TYPES = %w[public commercial]

afm wrote:

<select id="search_service_type" name="search[service_type]">
  <% $SERVICE_TYPES.length.times do |ctr| %>
    <option value="<%= ctr.to_s %>"><%= $SERVICE_TYPES[ctr] %></option>
  <% end %>
</select>

You can make the code a little more concise using the "each_with_index" method.

<select id="search_service_type" name="search[service_type]">
  <% SERVICE_TYPES.each_with_index do |service_type, index| %>
    <option value="<%= index %>"><%=h service_type %></option>
  <% end %>
</select>

You can also do this (below), although it doesn't have quite the same result.

<select id="search_service_type" name="search[service_type]">
  <%= options_for_select(SERVICE_TYPES) %>
</select>

Railscasts - Free Ruby on Rails Screencasts

10

Re: Global var for use in controllers and views?

ryanb wrote:

Global variables don't work well with Rails because they aren't shared across multiple FastCGI instances. Therefore, if one instance changes the variable, the other instance will not show the change. If you don't plan on changing the global variable, then best to use a constant.

Thanks for the heads up. Is this particular to FastCGI because I intend to use Mongrel, which I think is pure HTTP.

And if I want the global to be a constant I just put it in uppercase ie. $SERVICE_TYPES

Re: Global var for use in controllers and views?

ya the global vbariable that can be declared using @@ is not shared across different instances.if one action modifies it then an other calling action cannot access the modified.

if  this support was there then there was no need of using databases.we would store everything in a global variable and serve ppl without letting them access databases["provided the server never shuts down"].

Re: Global var for use in controllers and views?

Why not just use a constant?

If the values aren't going to change, you could put the variable as a constant in any class you like, as follows:

class ServiceTypes
    SERVICE_TYPES = %w{ public commercial }
end

Then in any of your code, view, model, controller or otherwise, you can just use:

ServiceTypes::SERVICE_TYPES

to reference that constant.  You could put the constant in any existing class as well, whatever works for you.