rubyvariablesruby-on-rails-4global-variablesactivesupport-concern

How can I set "global" variables that can be accessed in controllers and models in Rails


I have a table that has set entries. I would like to access those entries as variables in both my models and controllers without querying the database every time to set those variables.

I am able to get it to work by creating duplicate "concerns" for my models and controllers. I could also set global variables in my ApplicationController. Or i could initialize them in every place that I need them. What would be the correct rails way to set and access global variables that can be accessed in both controllers and models?

class ItemType
  has_many :items
end

class Item
  belongs_to :item_type
  belongs_to :foo
end

class Foo 
  has_many :items  

  def build_item
    bar_item_type = ItemType.find_by(:name => "bar")

    self.items.build(
      :foo_id => self.id,
      :item_type_id => bar_item_type.id
    )
  end
end

class ItemsController
  def update
    bar_item_type = ItemType.find_by(:name => "bar")

    @item.update(:item_type_id => bar_item_type.id)
  end

end

In the example, you can see that I am declaring the bar_item_type variable in both my Foo model and my ItemsController. I would like to DRY up my code base by being able to create and access that variable once for my rails project instead of having to make that same database call everywhere.


Solution

  • If you MUST use a constant, there are a few ways to do it. But you must take into account that you are instantiating an ActiveRecord model object which is dependent on data being present in the database. This is not recommend, because you now have model and controller logic relying on data being present in the database. This might be ok if you have seeded your database and that it won't change.

    class ItemType
      BAR_TYPE ||= where(:name => "bar").limit(1).first 
    
      has_many :items
    end
    

    Now where ever you need this object you can call it like this:

    bar_item_type  = ItemType::BAR_TYPE