11

I have a array of data, for example times (7:00am, 7:30am, etc.), that I want stored and referenced in a couple places.

1) Where should I store this data? I was originally thinking in my DB (I'm using mongoid) but I'm not sure if that's over kill.

2) How would I go about referencing it? Let's say, from a drop down menu.

Brandan
  • 14,735
  • 3
  • 56
  • 71
say
  • 2,585
  • 7
  • 35
  • 48

4 Answers4

6

In this kind of situation, I create a Constants module in lib:

module Constants
  SCHEDULER_STEPS = %w( 7:00am 7:30am )
end

Then I access it wherever I need with:

Constants::SCHEDULER_STEPS

Note: be sure to add libs to your autoload path in the configuration file.

apneadiving
  • 114,565
  • 26
  • 219
  • 213
  • Thanks for answering. I ended up creating a "global_constants.rb" file in "/config/initializers". The code I used was: http://d.pr/n/CMCW and used ":collection => Constants::BUSINESS_HOURS" in the select box to call the array. You way seems very similar, do you know of any benefit doing it your way? – say Sep 08 '12 at 20:26
  • I think yaml is overkill for your needs. Having constant defined in the class where it's used is the way to go if it's not shared, but you actually told it's "referenced in a couple of places". – apneadiving Sep 08 '12 at 20:34
  • That makes sense. Thanks for the explanation and please excuse the newbness. – say Sep 08 '12 at 20:40
  • 1
    It's better to ask questions than remain with doubts, there are no stupid questions :) – apneadiving Sep 08 '12 at 20:41
  • actually you did exactly what I told you, you just changed the path :) – apneadiving Sep 08 '12 at 20:47
  • I won't add too much info in initializers, actually, I only add there what is needed for Rails startup. Your constant module is not among those. Let `autoload` do it's job and avoid clutering your memory too soon, you'll gain boot time in the long run – apneadiving Sep 08 '12 at 20:48
2

I prefer to put this sort of data on the model it's most closely related to. For example, if the times in your example were the times to run a backup, put them in the Backup model with the rest of the behavior related to backups:

# app/models/backup.rb
class Backup < ActiveRecord::Base
  AVAILABLE_RUN_TIMES = %w{7:00am 7:30am ...}

  def run_at=(date)
    BackupSchedule.create(self, date)
  end
end

# app/views/backups/_form.html.erb
<%= select_tag(:run_at, options_for_select(Backup::AVAILABLE_RUN_TIMES)) %>

I've used the "big bucket of constants" approach too, but I would only use it if there's truly no more relevant place for the constants to live.

Brandan
  • 14,735
  • 3
  • 56
  • 71
2

For such kind of requirements i prefer

1st) create a config/app_constants.yml

Code here

production:
  time_list: "'7:00am','7:30am','7:40am'"
test:
  time_list: "'7:00am','7:30am','7:40am'"
development:
  time_list: "'7:00am','7:30am','7:40am'"

2nd Create under lib/app_constant.rb

module AppConstant
  extend self

  CONFIG_FILE = File.expand_path('../config/app_constants.yml', __FILE__)
  @@app_constants = YAML.load(File.read(CONFIG_FILE))
  @@constants = @@app_constants[Rails.env]

  def get_time_list
    @@constants['time_list'].split(',')
  end
end

3rd Call it anywhere like

AppConstant.get_time_list #will return an array

With this you just have to make changes at a single clean place(app_constants.yml) and will reflect throughout you application wherever AppConstant.get_time_list is used

AnkitG
  • 6,438
  • 7
  • 44
  • 72
2

I ended up creating a "global_constants.rb" file in "/config/initializers" with the following code:

module Constants
    BUSINESS_HOURS = ["6:00am","6:15am","6:30am","6:45am","7:00am"]
end

Then I called the data with Constants::BUSINESS_HOURS, specifically for the select box, the code was: <%= f.input :hrs_op_sun_open, :collection => Constants::BUSINESS_HOURS %>

Many of the answers here seem viable and I suspect they are all correct ways of doing what I needed.

say
  • 2,585
  • 7
  • 35
  • 48
  • 1
    Don't add useless initializers, this will slow your boot time. In this case, you should leverage the autoload and keep the file in `/lib` – apneadiving Sep 08 '12 at 20:55
  • Interesting. I moved the file into "/lib" and added "config.autoload_paths += %W(#{config.root}/lib)" to my "config/application.rb" file (inside of the Application class), restarted my server and it isn't working. Any idea what step I'm missing? – say Sep 08 '12 at 21:19
  • BTW, the error I am getting is "uninitialized constant ActionView::CompiledTemplates::Constants" – say Sep 08 '12 at 21:24
  • Replace `config.root` with `Rails.root` – apneadiving Sep 08 '12 at 21:40
  • Nice, it worked. I also had to rename the file form "global_constants.rb" to "constants.rb". Thanks again for the help. – say Sep 09 '12 at 00:59