[ruby-on-rails] Ruby on Rails: Where to define global constants?

I'm just getting started with my first Ruby on Rails webapp. I've got a bunch of different models, views, controllers, and so on.

I'm wanting to find a good place to stick definitions of truly global constants, that apply across my whole app. In particular, they apply both in the logic of my models, and in the decisions taken in my views. I cannot find any DRY place to put these definitions where they're available both to all my models and also in all my views.

To take a specific example, I want a constant COLOURS = ['white', 'blue', 'black', 'red', 'green']. This is used all over the place, in both models and views. Where can I define it in just one place so that it's accessible?

What I've tried:

  • Constant class variables in the model.rb file that they're most associated with, such as @@COLOURS = [...]. But I couldn't find a sane way to define it so that I can write in my views Card.COLOURS rather than something kludgy like Card.first.COLOURS.
  • A method on the model, something like def colours ['white',...] end - same problem.
  • A method in application_helper.rb - this is what I'm doing so far, but the helpers are only accessible in views, not in models
  • I think I might have tried something in application.rb or environment.rb, but those don't really seem right (and they don't seem to work either)

Is there just no way to define anything to be accessible both from models and from views? I mean, I know models and views should be separate, but surely in some domains there'll be times they need to refer to the same domain-specific knowledge?

This question is related to ruby-on-rails constants global

The answer is


Try to keep all constant at one place, In my application I have created constants folder inside initializers as follows:

enter image description here

and I usually keep all constant in these files.

In your case you can create file under constants folder as colors_constant.rb

colors_constant.rb

enter image description here

Don't forgot to restart server


Some options:

Using a constant:

class Card
  COLOURS = ['white', 'blue', 'black', 'red', 'green', 'yellow'].freeze
end

Lazy loaded using class instance variable:

class Card
  def self.colours
    @colours ||= ['white', 'blue', 'black', 'red', 'green', 'yellow'].freeze
  end
end

If it is a truly global constant (avoid global constants of this nature, though), you could also consider putting a top-level constant in config/initializers/my_constants.rb for example.


Another option, if you want to define your constants in one place:

module DSL
  module Constants
    MY_CONSTANT = 1
  end
end

But still make them globally visible without having to access them in fully qualified way:

DSL::Constants::MY_CONSTANT # => 1
MY_CONSTANT # => NameError: uninitialized constant MY_CONSTANT
Object.instance_eval { include DSL::Constants }
MY_CONSTANT # => 1

As of Rails 4.2, you can use the config.x property:

# config/application.rb (or config/custom.rb if you prefer)
config.x.colours.options = %w[white blue black red green]
config.x.colours.default = 'white'

Which will be available as:

Rails.configuration.x.colours.options
# => ["white", "blue", "black", "red", "green"]
Rails.configuration.x.colours.default
# => "white"

Another method of loading custom config:

# config/colours.yml
default: &default
  options:
    - white
    - blue
    - black
    - red
    - green
  default: white
development:
  *default
production:
  *default
# config/application.rb
config.colours = config_for(:colours)
Rails.configuration.colours
# => {"options"=>["white", "blue", "black", "red", "green"], "default"=>"white"}
Rails.configuration.colours['default']
# => "white"

In Rails 5 & 6, you can use the configuration object directly for custom configuration, in addition to config.x. However, it can only be used for non-nested configuration:

# config/application.rb
config.colours = %w[white blue black red green]

It will be available as:

Rails.configuration.colours
# => ["white", "blue", "black", "red", "green"]

Use a class method:

def self.colours
  ['white', 'red', 'black']
end

Then Model.colours will return that array. Alternatively, create an initializer and wrap the constants in a module to avoid namespace conflicts.


I typically have a 'lookup' model/table in my rails program and use it for the constants. It is very useful if the constants are going to be different for different environments. In addition, if you have a plan to extend them, say you want to add 'yellow' on a later date, you could simply add a new row to the lookup table and be done with it.

If you give the admin permissions to modify this table, they will not come to you for maintenance. :) DRY.

Here is how my migration code looks like:

class CreateLookups < ActiveRecord::Migration
  def change
    create_table :lookups do |t|
      t.string :group_key
      t.string :lookup_key
      t.string :lookup_value
      t.timestamps
    end
  end
end

I use seeds.rb to pre-populate it.

Lookup.find_or_create_by_group_key_and_lookup_key_and_lookup_value!(group_key: 'development_COLORS', lookup_key: 'color1', lookup_value: 'red');

For application-wide settings and for global constants I recommend to use Settingslogic. This settings are stored in YML file and can be accessed from models, views and controllers. Furthermore, you can create different settings for all your environments:

  # app/config/application.yml
  defaults: &defaults
    cool:
      sweet: nested settings
    neat_setting: 24
    awesome_setting: <%= "Did you know 5 + 5 = #{5 + 5}?" %>

    colors: "white blue black red green"

  development:
    <<: *defaults
    neat_setting: 800

  test:
    <<: *defaults

  production:
    <<: *defaults

Somewhere in the view (I prefer helper methods for such kind of stuff) or in a model you can get, for ex., array of colors Settings.colors.split(/\s/). It's very flexible. And you don't need to invent a bike.


The global variable should be declare in config/initializers directory

COLOURS = %w(white blue black red green)

A common place to put application-wide global constants is inside config/application.

module MyApp
  FOO ||= ENV.fetch('FOO', nil)
  BAR ||= %w(one two three)

  class Application < Rails::Application
    config.foo_bar = :baz
  end
end

According your condition, you can also define some environmental variables, and fetch it via ENV['some-var'] in ruby code, this solution may not fit for you, but I hope it may help others.

Example: you can create different files .development_env, .production_env, .test_env and load it according your application environments, check this gen dotenv-rails which automate this for your.


If a constant is needed in more than one class, I put it in config/initializers/contant.rb always in all caps (list of states below is truncated).

STATES = ['AK', 'AL', ... 'WI', 'WV', 'WY']

They are available through out the application except in model code as such:

    <%= form.label :states, %>
    <%= form.select :states, STATES, {} %>

To use the constant in a model, use attr_accessor to make the constant available.

class Customer < ActiveRecord::Base
    attr_accessor :STATES

    validates :state, inclusion: {in: STATES, message: "-- choose a State from the drop down list."}
end

Examples related to ruby-on-rails

Embed ruby within URL : Middleman Blog Titlecase all entries into a form_for text field Where do I put a single filter that filters methods in two controllers in Rails Empty brackets '[]' appearing when using .where How to integrate Dart into a Rails app Rails 2.3.4 Persisting Model on Validation Failure How to fix "Your Ruby version is 2.3.0, but your Gemfile specified 2.2.5" while server starting Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432? Rails: Can't verify CSRF token authenticity when making a POST request Uncaught ReferenceError: React is not defined

Examples related to constants

Constants in Kotlin -- what's a recommended way to create them? Why Is `Export Default Const` invalid? Proper use of const for defining functions in JavaScript Declaring static constants in ES6 classes? How can I get the size of an std::vector as an int? invalid use of non-static member function Why does JSHint throw a warning if I am using const? Differences Between vbLf, vbCrLf & vbCr Constants Constant pointer vs Pointer to constant Const in JavaScript: when to use it and is it necessary?

Examples related to global

How to access global variables Passing Variable through JavaScript from one html page to another page Change Button color onClick Can I make a function available in every controller in angular? How to declare a global variable in php? PHP pass variable to include Global Git ignore Passing a variable from one php include file to another: global vs. not Ruby on Rails: Where to define global constants? JavaScript: Global variables after Ajax requests