Where to call a global variable?

Hi guys,

I my application has to be all the "recent news, recent users, recent
pictures"-stuff. This is shown in a rendered view. Right now I'm using a
site controller getting data from different models like

@news = Article.find(:all, :limit => 3, :order => 'created_at DESC')

Of course that doesn't work anymore calling different contollers. I
thought about setting a global variable? I tried to put it in
apllication_helper but I get a nil-error by writing

def recent
  $news = Article.find(:all, :limit => 3, :order => 'created_at DESC')
end

and calling the following in the render

<% for news in $news %>
  <h5><%=h news.title %></h5>
  <p><%=h truncate(news.synopsis, 200) %></p>
  <p><a href="#" title="mehr" class="more">mehr...</a></p>
<% end %>

Is it fine to work with a global variable and if how to do that?

Greetings
Mayo

...well,

of course I have to call <%= recent %>, but anyway it's empty.

..solved, "I did it my way"

Site-Controller

def index
  @title ="Willkommen"
  @news = Article.find(:all, :limit => 3, :order => 'created_at DESC')
  $news = @news
end

Right now I don't know what happens with the variable at all. Looks like
that way, any controller, even called straight from a different site
will participate from the variable called and set by any user.

Every time a user calls the site-controller (well and it's the
index-site) the variable will be updated.

This doesn't seem like the best way to use a global variable. If you are
doing something like displaying those 3 articles on lots of pages, then
maybe you want something like this in application.rb:
before_filter :get_recent_articles

def get_recent_articles
  @articles = Article.recent
end

Then you will be able to access @articles in every view (with <%
articles.each do |article| %> etc). And you will have access to
@articles in all your controller actions.

You won't have access to @articles in your models though. But there you
could just call Article.recent.

Note: the above code uses a named scope like this (in article.rb)
named_scope :recent, :limit => 3, :order => 'created_at DESC'

What I'm suggesting doesn't sound perfect to me (I'm just writing this
quickly). But I think it is a better way to organize it than I global
variable.

... thanks Pau,

indeed you're right, and by the way, the same way has been suggested in
a different board.

Thanks alot, greetings
Mayo

I have always like constants for "global" variables. It comes from
programming C I think. Having model related constants in your
controllers is really not the MVC way IMHO. A constant is easy to
setup in ActiveRecord and in my opinion are much more readable. And
guess what, I actually did it with an Article model too! =>

class Article < ActiveRecord::Base
...
ARTS_CATEGORY = Category.find(:first, :conditions => ['name LIKE ?',
'arts%']).id
  OPINE_CATEGORY = Category.find(:first, :conditions => ['name
LIKE ?', 'opine%']).id
  DISTRACTIONS_CATEGORY = Category.find(:first, :conditions => ['name
LIKE ?', 'distra%']).id
  NEWS_POLITICS_CATEGORY = Category.find(:first, :conditions => ['name
LIKE ?', 'news%']).id

...

So in my controllers I use a method like this (the actual method is a
shared method for all "types" longer, this is for readability:
...
  def arts_archive
    Article.find_by_category_id(Article::ARTS_CATEGORY)
  end
...

blasterpal wrote:

class Article < ActiveRecord::Base
...
ARTS_CATEGORY = Category.find(:first, :conditions => ['name LIKE ?',
'arts%']).id
  OPINE_CATEGORY = Category.find(:first, :conditions => ['name
LIKE ?', 'opine%']).id
  DISTRACTIONS_CATEGORY = Category.find(:first, :conditions => ['name
LIKE ?', 'distra%']).id
  NEWS_POLITICS_CATEGORY = Category.find(:first, :conditions => ['name
LIKE ?', 'news%']).id

...

So in my controllers I use a method like this (the actual method is a
shared method for all "types" longer, this is for readability:
...
  def arts_archive
    Article.find_by_category_id(Article::ARTS_CATEGORY)
  end
...

I think a better way to do this is

class Category < ActiveRecord::Base
  has_many :articles #or has_one :article
  def self.arts
    # You could probably also do this with a named scope,
    # but I don't remember the syntax off the top of my
    # for selecting just one object.
    Category.find(:first, :conditions => ['name LIKE ?', 'arts%']).id
  end
end

and then in your controller:
  Category.arts.articles