Ruby on Rails: Where to define global constants?

前端 未结 12 1720
我在风中等你
我在风中等你 2020-11-28 00:44

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 plac

相关标签:
12条回答
  • 2020-11-28 01:07

    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.

    0 讨论(0)
  • 2020-11-28 01:10

    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
    
    0 讨论(0)
  • 2020-11-28 01:11

    The global variable should be declare in config/initializers directory

    COLOURS = %w(white blue black red green)
    
    0 讨论(0)
  • 2020-11-28 01:12

    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.

    0 讨论(0)
  • 2020-11-28 01:12

    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
    
    0 讨论(0)
  • 2020-11-28 01:13

    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');
    
    0 讨论(0)
提交回复
热议问题