Forum: Ruby on Rails Where to call a global variable?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Mario P. (Guest)
on 2008-11-15 12:16
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
Mario P. (Guest)
on 2008-11-15 12:21
...well,

of course I have to call <%= recent %>, but anyway it's empty.
Mario P. (Guest)
on 2008-11-15 14:00
..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.
Pau C. (Guest)
on 2008-11-15 18:30
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.
Mario P. (Guest)
on 2008-11-15 21:47
... thanks Pau,

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

Thanks alot, greetings
Mayo
blasterpal (Guest)
on 2008-11-16 16:28
(Received via mailing list)
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
...


On Nov 15, 2:47 pm, Mario Peterscheck <rails-mailing-l...@andreas-
Pau C. (Guest)
on 2008-11-16 17:25
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
This topic is locked and can not be replied to.