Howto add application-wide variables?

I suspect this is something I should know already but I can’t seem to
get it right, how can I create application wide variables and have them
accessible to all my controllers?

I tried creating a plugin and having my controller require a specific
method from that plugin to access its variables but that didn’t work, so
I am left scratching my head.

eg from plugin ./vendor/plugins/myplugin/shared_defs.rb file

Module SharedDefs
def load_shared_defs
@var1 = something
@var2 = something_else
end
end

eg from controller
include SharedDefs
require :load_shared_defs

def index
@my_stuff = @var1
end

@var1 is not defined and so my guess is my scope is off or I’m not
accessing it correctly but I am not sure which.

Thanks in advance for any light you can shed! :slight_smile:

-Andy

Cool !!

thanx

If you ever need to share something between multiple controllers, it
often goes in the ApplicationController (application.rb) class. Since
all controllers inherit from this class, they will inherit any
instance variables set. You can set a method up as a “before_filter”
so it is called before each action to prepare any variables. For
example:

application.rb

class ApplicationController < ActionController::Base
before_filter :prepare_variables

def prepare_variables
@var1 = something
@var2 = something_else
end
end

However, design-wise, there may be better alternatives depending upon
what you are trying to accomplish. For example, if the variable
doesn’t change, it may be better to use a constant. Or, if you are
just setting up some default variables that the controller can
override, you may be able to use logic in the view to handle this.
For example, instead of this:

application.rb

class ApplicationController < ActionController::Base
before_filter :prepare_variables

def prepare_variables
@title = ‘Default Title’
end
end

You can place the default in the view like this:

application.rhtml

<%= @title || 'Default Title' %> ...

This would display ‘Default Title’ as the page title if the
controller hasn’t set the @title instance variable.

Hope that helps.

Ryan

On 6/04/2006, at 9:10 AM, Andrew G. Cowan wrote:

I suspect this is something I should know already but I can’t seem
to get it right, how can I create application wide variables and
have them accessible to all my controllers?

While the solutions posted are fine for constant values, if you want
to change the values during runtime they will not work when you have
to scale up your application. Use the database.


Phillip H.
[email protected]
http://www.sitharus.com/

On Apr 5, 2006, at 6:06 PM, Phillip H. wrote:

While the solutions posted are fine for constant values, if you
want to change the values during runtime they will not work when
you have to scale up your application. Use the database.

Could you explain this a little more? Are you referring to setting
instance variables in the ApplicationController? I’m curious why this
wouldn’t work when scaling up the application. Thanks.

One more thing I forgot to include in my previous example. If you use
a before_filter, you should make the method private so it is not
considered an action. See the documentation for an example.

http://api.rubyonrails.com/classes/ActionController/Filters/
ClassMethods.html

Ryan

Ryan B. wrote:

On Apr 5, 2006, at 6:06 PM, Phillip H. wrote:

While the solutions posted are fine for constant values, if you want
to change the values during runtime they will not work when you have
to scale up your application. Use the database.

Could you explain this a little more? Are you referring to setting
instance variables in the ApplicationController? I’m curious why this
wouldn’t work when scaling up the application. Thanks.

If you go beyond using WEBrick, you will be using a technology such as
FastCGI which has a pool of request-handling processes. Changing a value
in memory will only have an effect in the process in which the change
happens - the other processes won’t see the change.

So to share a variable across the application it must be in the
database, or in the filestore, or in a separate shared service (e.g.
using Distributed Ruby).

regards

Justin

This is exactly the information I was looking, thank you so much for
pointing this out Ryan! :slight_smile:

-Andy

Ryan B. wrote:

If you ever need to share something between multiple controllers, it
often goes in the ApplicationController (application.rb) class. Since
all controllers inherit from this class, they will inherit any
instance variables set. You can set a method up as a “before_filter”
so it is called before each action to prepare any variables. For
example:

application.rb

class ApplicationController < ActionController::Base
before_filter :prepare_variables

def prepare_variables
@var1 = something
@var2 = something_else
end
end

However, design-wise, there may be better alternatives depending upon
what you are trying to accomplish. For example, if the variable
doesn’t change, it may be better to use a constant. Or, if you are
just setting up some default variables that the controller can
override, you may be able to use logic in the view to handle this.
For example, instead of this:

application.rb

class ApplicationController < ActionController::Base
before_filter :prepare_variables

def prepare_variables
@title = ‘Default Title’
end
end

You can place the default in the view like this:

application.rhtml

<%= @title || 'Default Title' %> ...

This would display ‘Default Title’ as the page title if the
controller hasn’t set the @title instance variable.

Hope that helps.

Ryan