set configuration constants depending on environment in rails - ruby-on-rails

I would like to define a constant (like the admin-email-adress) depending on the environment. What is the easiest way to do this?
I'd like something like that, in development.rb (or test or production.rb):
ADMIN_EMAIL = "foo#bar.com"
And be able to access it by calling something like
ADMIN_EMAIL
Is there an easy way or do I have to do something like creating a module and initialize it and stuff (and in case you're wondering if I have any idea about this, unfortunately: I don't)
It works this way, but one has to
restart the server, for the constants
to take effect.

In config/environments/, there are some configuration files that get executed based on what environment you're currently in. Try defining a constant in one of those.

Related

How to use database.yml define json file for each environment

I working on json file format in rails.
I like to use environment in config/databse.yml (or better place) to define what json file to use in the app.
But have no idea, unable to find any sample.
Any help please.
Existing code in helper as follow
def get_table(foo)
get_data = if [:production, :sandbox].include?(Rails.env)
File.read("support/product.json")
else
File.read("support/sample.json")
end
JSON.parse(get_data)
end
If I understand you correctly then you are trying to load a JSON file based on the current environment? I'm not sure a JSON file is really the kind of data store you are looking for... but that is a different question.
In your case, I would use an environment variable to set the file name that is to be used during the execution of the application.
Change the helper to something like:
def get_table
database_content_from_file = File.read(ENV['database_file'])
JSON.parse(get_data)
end
You can now set the environment variable 'database_file' in each of your different types of environments. This can be done by setting a system-wide variable or using a gem like https://github.com/laserlemon/figaro (which I highly encourage you to use).
With this, you could set ENV['database_file'] to 'support/sample.json' in your development environment and set it to 'support/product.json' in production.
I hope this answers your question. If not please rephrase your question in a manner that is easier to understand.

Mock Rails 4 application config custom value

In Rails::Application, I add a custom configuration using...
config.x.cache_config = config_for(:cache)
In my tests, I want to see how code using this behaves depending on how the configuration is defined in cache.yml. To set the various conditions in my rspec tests, I want to do something like...
allow(Rails.application.config.x).to recieve(:cache_config).and_return({})
But this doesn't work. It gets an error stating
#<Rails::Application::Configuration::Custom ... > does not implement: cache_config
After much digging and testing in pry, I figured this out.
Short answer:
allow(Rails.application.config.x).to receive(:method_missing).with(:cache_config).and_return({})
Everything in this statement has to be exact except...
replace :cache_config with the name of your custom configuration key
replace {} in the and_return({}) with the mock value you want to set for the key
Longer answer:
If you want to dig into why this is, since it is not at all obvious, check out the code at...
Custom class in Rails::Application::Configuration
Creation of #x for custom configs in Rails::Application::Configuration
In case this helps anyone using Mocha, I ended up doing this in a helper
Rails.application.config.x.stubs(:my_config).returns(true)
yield
Rails.application.config.x.unstub(:my_config)
The method_missing trick above didn't work for some reason (guessing to do with differences in the way the stubbing is implemented), failing with an error message about the Configuration::Custom class not responding to method_missing the first time it was referenced for a different piece of config.
Adding to the above answer(s), if you want to stub nested config, then you have to make sure that you're allow-ing the second-last piece in the config to receive(:method_missing), as such:
allow(Rails.application.config.x.foo.bar).to receive(:method_missing).with(:foobar).and_return(:baz)
The above code stubs the Rails.application.config.x.foo.bar.foobar config to return :baz.

How to share constant in different controllers and models and view in Rails 3

What is the best practice to share an global variable
eg: host = test123.com
and I Can use "host" every where ?
I will used it as CONSTANT to show my email in many places,
So I don't want to hardcode my email address everywhere!
Thanks~
I will typically create a file in my initializer directory or add to my environment (devel or production) and declare my variable with caps.
production.rb
SECRET_KEY = "blahblah"
Then across my app, I can reference to this variable by using the ENV
So, in my view, I would type ENV["SECRET_KEY"] or just SECRET_KEY
You should really avoid doing this. That being said, ::HOST = 'test123.com'
I will used it as CONSTANT to show my email in many places,
if you are only using this for display purposes - then consider putting it in en.yml file (and other locale files if desired)
see http://guides.rubyonrails.org/i18n.html#adding-translations
Just check this out http://railscasts.com/episodes/85-yaml-configuration-file . This is the standard way of defining global configurations in Rails app.

Rails where to put configuration like ini files?

When coding with PHP I always separate configuration values like perPage value in a separated ini file. How are you Ruby masters do this with Rails?
I would like to access config values inside my model, controller and view.
Thx!
I've generally just used a plugin like http://github.com/cjbottaro/app_config or wrote my own. I like using a config.yml file in the config directory.
There isn't really anything built in to rails to do this, but luckily there's a great plugin called settingslogic which lets you externalise your settings.
Having said that I personally like to make these things constants in my model, so for example I'd have something like this:
class Person < AR:B
DEFAULT_PER_PAGE = 10
end
Not sure about masters :) but mortal developers can usually leverage some of the existing plugins like this one: http://www.workingwithrails.com/railsplugin/5324-app-config
There are actually quite a few of them, so you'll probably find something that will suit you.

What is the best way to store app specific configuration in rails?

I need to store app specific configuration in rails. But it has to be:
reachable in any file (model, view, helpers and controllers
environment specified (or not), that means each environment can overwrite the configs specified in environment.rb
I've tried to use environment.rb and put something like
USE_USER_APP = true
that worked to me but when trying to overwrite it in a specific environment it wont work because production.rb, for instance, seems to be inside the Rails:Initializer.run block.
So, anyone?
Look at Configatron: http://github.com/markbates/configatron/tree/master
I have yet to use it, but he's actively developing it now, and looks quite nice.
I was helping a friend set up the solution mentioned by Ricardo yesterday. We hacked it a bit by loading the YAML file with something similar to this (going from memory here):
require 'ostruct'
require 'yaml'
require 'erb'
#config = OpenStruct.new(YAML.load_file("#{RAILS_ROOT}/config/config.yml"))
config = OpenStruct.new(YAML.load(ERB.new(File.read("#{RAILS_ROOT}/config/config.yml")).result))
env_config = config.send(RAILS_ENV)
config.common.update(env_config) unless env_config.nil?
::AppConfig = OpenStruct.new(config.common)
This allowed him to embed Ruby code in the config, like in Rhtml:
development:
path_to_something: <%= RAILS_ROOT %>/config/something.yml
The most basic thing to do is to set a class variable from your environment.rb. I've done this for Google Analytics. Essentially I want a different key depending on which environment I'm in so development or staging don't skew the metrics.
This is how I did it.
In lib/analytics/google_analytics.rb:
module Analytics
class GoogleAnalytics
##account_id = nil
cattr_accessor :account_id
end
end
And then in environment.rb or in environments/production.rb or any of the other environment files:
Analytics::GoogleAnalytics.account_id = "xxxxxxxxx"
Then anywhere you ned to reference, say the default layout with the Google Analytics JavaScript, it you just call Analytics::GoogleAnalytics.account_id.
I found a good way here
Use environment variables. Heroku uses this. Remember that if you keep configuration in the codebase, anyone with access to the code has access to any secret configuration (aws api keys, gateway api keys, etc).
daemontool's envdir is a good tool for setting configuration, I'm pretty sure that's what Heroku uses to give application their environment variables.
I have used Rails Settings Cached.
It is very simple to use, keeps your configuration values cached and allows you to change them dynamically.

Resources