I am using the sorcery gem in a Rails 6 application.
I need to use variable in sorcery.rb at controller, however I do not know how to get the value.
Rails.application.config.sorcery.submodules = [:user_activation]
Rails.application.config.sorcery.configure do |config|
config.user_config do |user|
user.activation_token_expiration_period = 60 * 60 * 24 * 7 # <= this
end
end
How can I get this?
If you have an instance of User you can do it this way:
User.new.sorcery_config.activation_token_expiration_period
You can keep this token expiration period in a config file instead and use it anywhere required. There are many ways you can set the config (my preferred way is):
Add a config.yml file inside config folder:
defaults: &defaults
activation_token_expiration_period: 60 * 60 * 24 * 7
development:
<<: *defaults
test:
<<: *defaults
production:
<<: *defaults
And then in application.rb file you can do like this:
APP_CONFIG = YAML.load_file('config/config.yml')[Rails.env]
And then use it anywhere in the application like this:
APP_CONFIG['activation_token_expiration_period']
So in your case you can do like this:
Rails.application.config.sorcery.configure do |config|
config.user_config do |user|
user.activation_token_expiration_period = APP_CONFIG['activation_token_expiration_period']
end
end
You can set this config in any way (you might be having this already setup in your application), the primary suggestion is to use an environment variable to store this value and use it in the application wherever required.
Using APP_CONFIG to store values for system-wide access, works great but not for ActionMailer email views. Does anyone knows how to fix this?
In load_config.rb (config folder) i load it like:
APP_CONFIG = YAML.load_file("#{Rails.root}/config/application.yml")[Rails.env]
Then in my Mailer views (HAML) I try to use them like regularly in my application like:
Welcome to our application named:
= APP_CONFIG['app_name']
How would i get access to all my APP_CONFIG values inside action mailer views?
Try to something like this:
app/controllers/user_controller.rb
def some_method
app_name = APP_CONFIG['app_name']
UserMailer.welcome_mail(app_name).deliver
end
app/mailers/user_mailer.rb
class UserMailer < ActionMailer::Base
default :from => "info#mypage.com"
def welcome_mail(app_name)
#app_name = app_name
mail(:to => "test#mypage.com", :subject => "[system] User Welcome!")
end
end
app/views/user_mailer/welcome_mail.html.haml
%p Welcome to our application named:
=#app_name
I think it should work.
I fixed it like this:
default: &default
app_name: "My APP"
app_mail: "info#..."
development:
<<: *default
...
production:
<<: *default
...
The problem was it was using the RAILS_ENV and I had not merged the default section into the production and development mode, like this its clean and you can just do APP_CONFIG["any_var"] having the default (global) ones to store google analytics etc and the ENV specific ones under development and production :)
I am trying to use different stripe keys (a credit card payment processing system) depending on whether I'm in test/development or production/ Based on suggestions I've seen on StackOverflow, I did the following:
In my /config/initalizers/stripe.rb file, I have the following:
STRIPE_CONFIG = begin
config = YAML.load(File.open(Rails.root.join('config', 'stripe.yml')))
config = config[Rails.env] || {}
config.to_options
end
and in my /config/stripe.yml file, I have the following:
default: &default
Stripe.api_key: "testapikeycode"
STRIPE_PUBLIC_KEY: "testpublickeycode"
development:
<<: *default
test:
<<: *default
production:
Stripe.api_key: "productionapikeycode"
STRIPE_PUBLIC_KEY: "productionpublickeycode"
However, when I go into the console (rails console), and I type
puts STRIPE_PUBLIC_KEY
I get the following error message:
NameError: uninitialized constant STRIPE_PUBLIC_KEY
Any ideas?
Alternate method
Only use stripe.rb, and have the following in it:
if Rails.env == 'production'
Stripe.api_key: "productionapikeycode"
STRIPE_PUBLIC_KEY: "productionpublickeycode"
else
Stripe.api_key: "tesapikeycode"
STRIPE_PUBLIC_KEY: "testpublickeycode"
end
STRIPE_PUBLIC_KEY is a key in your yaml config file, you never actually initialize it as a constant. If you type p STRIPE_CONFIG['STRIPE_PUBLIC_KEY'] instead you should get the result you want.
Aside I think YAML.load should be YAML.load_file.
In my app, I have many constants, so I made a constants file named det_constants.yml for these constants.
/config/det_constants.yml
DEFAULTS: &DEFAULTS
company_type: { "Private" : 1,
"Public" : 2 }
development:
<<: *DEFAULTS
test:
<<: *DEFAULTS
production:
<<: *DEFAULTS
I have a constants.rb file in lib folder, which loads this constant file.
/lib/constants.rb
module Constants
# Allows accessing config variables from det_constants.yml like so:
# Constants[:abc] => xyz
def self.[](key)
unless #config
raw_config = File.read(Rails.root.to_s + "/config/det_constants.yml")
#config = YAML.load(raw_config)[Rails.env].symbolize_keys
end
#config[key]
end
def self.[]=(key, value)
#config[key.to_sym] = value
end
end
In my view file, when I do
<%= Constants[:company_type] %>
it throws an error
NameError in Vendors#index
uninitialized constant ActionView::CompiledTemplates::Constants
at line
<%= Constants[:company_type] %>
However, If i do the same thing in console, it runs properly,
ruby-1.9.2-head > Constants[:company_type]
=> {"Private"=>1, "Public"=>2}
I don't know where is the problem. if there is a new and better way to do this in Rails 3, please let me know.
Ruby version: ruby 1.9.2p110 (2010-12-20 revision 30269) [i686-linux]
Rails version: Rails 3.0.3
I imagine you need:
<% require 'constants' %>
Also, you will need to restart the server following changes in lib/; it doesn't catch them automatically even in development mode.
What about other solutions, I recommend you watch the railscast called YAML Configuration File. There are also some gems such as Settingslogic to help you with that.
I need to create one config option for my Rails application. It can be the same for all environments. I found that if I set it in environment.rb, it's available in my views, which is exactly what I want...
environment.rb
AUDIOCAST_URI_FORMAT = http://blablalba/blabbitybla/yadda
Works great.
However, I'm a little uneasy. Is this a good way to do it? Is there a way that's more hip?
For general application configuration that doesn't need to be stored in a database table, I like to create a config.yml file within the config directory. For your example, it might look like this:
defaults: &defaults
audiocast_uri_format: http://blablalba/blabbitybla/yadda
development:
<<: *defaults
test:
<<: *defaults
production:
<<: *defaults
This configuration file gets loaded from a custom initializer in config/initializers:
# Rails 2
APP_CONFIG = YAML.load_file("#{RAILS_ROOT}/config/config.yml")[RAILS_ENV]
# Rails 3+
APP_CONFIG = YAML.load_file(Rails.root.join('config/config.yml'))[Rails.env]
If you're using Rails 3, ensure you don't accidentally add a leading slash to your relative config path.
You can then retrieve the value using:
uri_format = APP_CONFIG['audiocast_uri_format']
See this Railscast for full details.
Rails 3 version of initialiser code is as follows (RAILS_ROOT & RAILS_ENV are deprecated)
APP_CONFIG = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env]
Also, Ruby 1.9.3 uses Psych which makes merge keys case sensitive so you'll need to change your config file to take that into account, e.g.
defaults: &DEFAULTS
audiocast_uri_format: http://blablalba/blabbitybla/yadda
development:
<<: *DEFAULTS
test:
<<: *DEFAULTS
production:
<<: *DEFAULTS
Rails >= 4.2
Just create a YAML file into config/ directory, for example: config/neo4j.yml.
Content of neo4j.yml can be somthing like below(For simplicity, I used default for all environments):
default: &default
host: localhost
port: 7474
username: neo4j
password: root
development:
<<: *default
test:
<<: *default
production:
<<: *default
in config/application.rb:
module MyApp
class Application < Rails::Application
config.neo4j = config_for(:neo4j)
end
end
Now, your custom config is accessible like below:
Rails.configuration.neo4j['host'] #=>localhost
Rails.configuration.neo4j['port'] #=>7474
More info
Rails official API document describes config_for method as:
Convenience for loading config/foo.yml for the current Rails env.
If you do not want to use a yaml file
As Rails official guide says:
You can configure your own code through the Rails configuration object with custom configuration under the config.x property.
Example
config.x.payment_processing.schedule = :daily
config.x.payment_processing.retries = 3
config.x.super_debugger = true
These configuration points are then available through the configuration object:
Rails.configuration.x.payment_processing.schedule # => :daily
Rails.configuration.x.payment_processing.retries # => 3
Rails.configuration.x.super_debugger # => true
Rails.configuration.x.super_debugger.not_set # => nil
Official Reference for config_for method |
Official Rails Guide
Step 1: Create config/initializers/appconfig.rb
require 'ostruct'
require 'yaml'
all_config = YAML.load_file("#{Rails.root}/config/config.yml") || {}
env_config = all_config[Rails.env] || {}
AppConfig = OpenStruct.new(env_config)
Step 2: Create config/config.yml
common: &common
facebook:
key: 'asdjhasxas'
secret : 'xyz'
twitter:
key: 'asdjhasxas'
secret : 'abx'
development:
<<: *common
test:
<<: *common
production:
<<: *common
Step 3: Get constants anywhere in the code
facebook_key = AppConfig.facebook['key']
twitter_key = AppConfig.twitter['key']
I just wanted to update this for the latest cool stuff in Rails 4.2 and 5, you can now do this inside any of your config/**/*.rb files:
config.x.whatever = 42
(and that's a literal x in there, ie. the config.x. literally must be that, and then you can add whatever you want after the x)
...and this will be available in your app as:
Rails.configuration.x.whatever
See more here: http://guides.rubyonrails.org/configuring.html#custom-configuration
Just some extra info on this topic:
APP_CONFIG = YAML.load_file(Rails.root.join('config', 'config.yml'))[Rails.env].with_indifferent_access
".with_indifferent_access" allows you to access the values in the hash using a string key or with an equivalent symbol key.
eg.
APP_CONFIG['audiocast_uri_format'] => 'http://blablalba/blabbitybla/yadda'
APP_CONFIG[:audiocast_uri_format] => 'http://blablalba/blabbitybla/yadda'
Purely a convenience thing, but I prefer to have my keys represented as symbols.
I use something similar to John for Rails 3.0/3.1, but I have erb parse the file first:
APP_CONFIG = YAML.load(ERB.new(File.new(File.expand_path('../config.yml', __FILE__)).read).result)[Rails.env]
This allows me to use ERB in my config if I need to, like reading heroku's redistogo url:
production:
<<: *default
redis: <%= ENV['REDISTOGO_URL'] %>
Rails 4
To create a custom configuration yaml and load it (and make available to your app) similar to how database_configuration.
Create your *.yml, in my case I needed a redis configuration file.
config/redis.yml
default: &default
host: localhost
port: 6379
development:
<<: *default
test:
<<: *default
production:
<<: *default
host: <%= ENV['ELASTICACHE_HOST'] %>
port: <%= ENV['ELASTICACHE_PORT'] %>
Then load the configuration
config/application.rb
module MyApp
class Application < Rails::Application
## http://guides.rubyonrails.org/configuring.html#initialization-events
config.before_initialize do
Rails.configuration.redis_configuration = YAML.load_file("#{Rails.root}/config/redis.yml")
end
end
end
Access the values:
Rails.configuration.redis_configuration[Rails.env] similar to how you can have access to your database.yml by Rails.configuration.database_configuration[Rails.env]
Building on Omer Aslam's elegant solution, I decided to convert the keys into symbols. The only change is:
all_config = YAML.load_file("#{Rails.root}/config/config.yml").with_indifferent_access || {}
This allows you to then reference values by symbols as keys, e.g.
AppConfig[:twitter][:key]
This seems neater to my eyes.
(Posted as an answer as my reputation isn't high enough to comment on Omer's reply)
I like simpleconfig. It allows you to have per environment configuration.
see my response to Where is the best place to store application parameters : database, file, code...?
A variation to what you had in that it's a simple reference to another file. It sees that environment.rb isn't constantly updated and doesn't have a heap of app specific stuff in it.
Though not a specific answer to your question of 'is it the Rails way?', perhaps there'll be some discussion there about that.
I prefer accessing settings through the global application stack. I avoid excess global variables in local scope.
config/initializers/myconfig.rb
MyAppName::Application.define_singleton_method("myconfig") {YAML.load_file("#{Rails.root}/config/myconfig.yml") || {}}
And access it with.
MyAppName::Application.myconfig["yamlstuff"]
My way to load Settings before Rails initialize
Allows you to use settings in Rails initialization and configure settings per environment
# config/application.rb
Bundler.require(*Rails.groups)
mode = ENV['RAILS_ENV'] || 'development'
file = File.dirname(__FILE__).concat('/settings.yml')
Settings = YAML.load_file(file).fetch(mode)
Settings.define_singleton_method(:method_missing) {|name| self.fetch(name.to_s, nil)}
You could get settings in two ways:
Settings['email'] or Settings.email
My best way to custom config, with raise message when setting.yml is missing.
gets loaded from a custom initializer in config/initializers/custom_config.rb
setting_config = File.join(Rails.root,'config','setting.yml')
raise "#{setting_config} is missing!" unless File.exists? setting_config
config = YAML.load_file(setting_config)[Rails.env].symbolize_keys
#APP_ID = config[:app_id]
#APP_SECRET = config[:app_secret]
Create a YAML in config/setting.yml
development:
app_id: 433387212345678
app_secret: f43df96fc4f65904083b679412345678
test:
app_id: 148166412121212
app_secret: 7409bda8139554d11173a32222121212
production:
app_id: 148166412121212
app_secret: 7409bda8139554d11173a32222121212