Accessing Rails environment config in Rake namespace - ruby-on-rails

I have a path defined in my environment.rb file
MyRailsApp::Application.configure do
config.xml_import_path = "/path/to/xml"
end
I'd like to be able to set a variableaccess these within a Rake file like this
namespace :myapp do
xml_path = MyRailsApp::Application.config.xml_import_path
task :first_task => :environment do
# do some stuff with xml_path
end
task :second_task => :environment do
# do some other stuff with xml_path
end
end
but I keep getting an error when I run rake myapp:first_task
undefined method `xml_import_path' for #<Rails::Application::Configuration:0x00000006a98bd8>
I guess it's something to do with the environment no being loaded, as it works if I put
xml_path = MyRailsApp::Application.config.xml_import_path
inside the task definition.
Is there any way to use config values set in environment.rb like I am attempting to do?
Is there a better/right way to do it?
cheers,
Luke

Is there any way to use config values set in environment.rb like I am attempting to do?
yes you can load your Rails Environment into any script
just add
ENV['RAILS_ENV'] = ARGV.first || ENV['RAILS_ENV'] || 'development'
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
before you call the variable you want to call
however, the best way to load the environment in your case is to add the above code to the bin/rake file or the config/boot.rb one
reference: https://shifteleven.com/articles/2006/10/08/loading-your-rails-environment-into-a-script/
Another way is to use the dotenv gem and save the path in the .env the file then load that var in your environment.rb and rake file

Related

Rails precompile constant uninitialized

I wanted to preload the configuration (from ".yml" files). In one of my initializer files (config/initializers/facebook.rb) I have following line of code:
FACEBOOK_CONFIG = YAML.load_file("#{Rails.root}/config/facebook.yml")[Rails.env]
So, it works like a charm in the "DEVELOPMENT" mode. Once I switch to the production mode, it keeps telling me, that FACEBOOK_CONFIG is an uninitialized constant for my "facebook.js.coffee.erb" file, located in assets/javascript (If it matters), if I want to o "rake assets:precompile". I've tried doing random stuff, like: RAILS_ENV=production bundle exec rake assets:precompile or
rake assets:precompile:all
, but no luck
I have tried assigning "initialize_on_precompile = true" variable for my production environment (although, it should be true by default), just in case.
Why it doesn't work in production mode (But, I want to emphasise, that it does work(!) in the development environment).
Can someone help with that one ?
I encountered exactly the same problem. This is because your javascript(coffescript) file makes reference to a constant that is defined in an initializer. Because it is precompiled before the initializer the app throws an error.
This is the simple solution I found. You place this code at the bottom of your application.rb file in config:
module AssetsInitializers
class Railtie < Rails::Railtie
initializer "assets_initializers.initialize_rails",
:group => :assets do |app|
require "#{Rails.root}/config/initializers/facebook.rb"
end
end
end
It manually loads up certain files from the initializer folder. It solved my problem.
Hopefully this was the issue for you as well.
module Rails
class << self
def facebook_config
##facebook_config ||= nil
end
def facebook_config=(facebook_config)
##facebook_config = facebook_config
end
end
end
Rails.facebook_config = YAML.load_file("#{Rails.root}/config/facebook.yml")[Rails.env]
# And you can use it like this in anywhere:
puts Rails.facebook_config

Changing a rake task to work on test environment

namespace :fixtures do
namespace :load do
task :prepare => :environment do
ENV['FIXTURES_PATH'] = "spec/fixtures"
ENV['RAILS_ENV'] ||= "test"
puts ENV.inspect
Rake::Task["db:fixtures:load"].invoke
end
end
end
I have added this to a special.rake file in ./lib/tasks in order to cause the rake db:fixtures:load command to apply to fixtures in the spec/fixtures directory, and to apply to the test environment.
It's not working. Where have I gone wrong?
You need to reconnect to the database. Something like
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations["test"])
Changing ENV['RAILS_ENV'] after environment is already loaded doesn't do anything.
Perhaps it would also work if you load the environment task after you change ENV, but not sure about that:
task :prepare do
ENV['RAILS_ENV'] ||= "test"
Rake::Task["environment"].invoke
Rake::Task["db:fixtures:load"].invoke
end

How do I get file name of the file currently being tested by rake

In my rake task if I want to know the name of the file when that file is picked up for testing then how do I do that. Reason is that some of the files produce warning. I am not sure which of my 800 tests is producing warning.
My rake task is something like this. I am using rails3.
Rake::TestTask.new(:test_hr_module) do |t|
t.libs << 'test'
t.test_files = Dir.glob('test/{hr}/**/*_test.rb').sort
t.warning = true
t.verbose = true
end
You can always call single files:
ruby test/unit/model_test.rb
You can even use the name flag to only run specific tests
ruby test/unit/model_test.rb -n test_name
You'll probably need to change require 'test_helper' to require 'test/test_helper' in the test file though.
If you really need to do this in a rake task could you try:
Dir.glob('test/**/*_test.rb').each do |f|
puts `ruby #{f}`
end
end
Perhaps you can use the pseudo-variable __FILE__ to achieve this?

Correct Ruby on Rails 3 replacement for ENV["RAILS_ENV"] ||= 'production'?

We're doing an upgrade to Ruby on Rails 3 (like half the world right now), and I've been diligently replacing usages of RAILS_ENV, for example
RAILS_ENV == 'wibble'
# becomes
Rails.env.wibble?
But I'm not as certain of what to do with:
ENV["RAILS_ENV"] ||= 'production'
We've got it at the top of a whole bunch of Rake tasks and daemons, and the idea is that you can pass RAILS_ENV on the command-line, but it defaults to 'production' if it's not passed.
I'm not sure of the new Rails3-appropriate way of doing this. So for now my rails:upgrade:check is complaining mightily of this intrusion of Rails2-ishness...
I don't know if:
::Rails.env ||= 'production'
will work.
Does Rails.env exist in a daemon?
Does it automagickally get pre-populated with the value of RAILS_ENV passed on the command-line or do we need a new way of invoking the daemons?
What is the correct mantra for this?
Update:
Looking into the source-code for Rails.env,
def env
#_env ||= ActiveSupport::StringInquirer.new(RAILS_ENV)
end
we can deduce a number of things.
Firstly, it looks like RAILS_ENV does actually still exist - which means it can be set and Rails.env will find it...
If Rails is valid in the context of a daemon, then nothing more needs to be done. If not - then I could just not care much and use the old RAILS_ENV as before.
Rails.env is actually of type ActiveSupport::StringInquirer, which overrides method_missing in order to provide that nice equality syntax. Check: http://api.rubyonrails.org/classes/ActiveSupport/StringInquirer.html
So, if you want to override it to be "production" by defaut, you should write:
Rails.env ||= ActiveSupport::StringInquirer.new('production')
However, you'll have to check which is the uninitialized value of Rails.env, I'm not sure it's really nil.
The best course of action, IMO, is to just prepend env RAILS_ENV=production to all your scripts.
Edit lib/tasks/environments.rake
# Sets environments as needed for rake tasks
%w[development production staging].each do |env|
desc "Runs the following task in the #{env} environment"
task env do
Rails.env = env
end
end
task :testing do
Rake::Task["test"].invoke
end
task :dev do
Rake::Task["development"].invoke
end
task :prod do
Rake::Task["production"].invoke
end
Source
UPDATE
pass RAILS_ENV=production via command line, something like this:
RAILS_ENV=production rake db:setup
Does this help:
# before
if RAILS_ENV == 'production'
...
# Rails 3
if Rails.env.production?
if Rails.env.production?
puts '...'

How do I make Rake tasks run under my Sinantra app/environment?

I'm using Sinatra, and I wanted to set up some of the convenience rake tasks that Rails has, specifically rake db:seed.
My first pass was this:
namespace :db do
desc 'Load the seed data from db/seeds.rb'
task :seed do
seed_file = File.join(File.dirname(__FILE__), 'db', 'seeds.rb')
system("racksh < #{seed_file}")
end
end
racksh is a gem that mimics Rails' console. So I was just feeding the code in the seed file directly into it. It works, but it's obviously not ideal. What I'd like to do is create an environment task that allows commands to be run under the Sinanta app/environment, like so:
task :environment do
# what goes here?
end
task :seed => :environment do
seed_file = File.join(File.dirname(__FILE__), 'db', 'seeds.rb')
load(seed_file) if File.exist?(seed_file)
end
But what I can't figure out is how to set up the environment so the rake tasks can run under it. Any help would be much appreciated.
I've set up a Rakefile for Sinatra using a kind of Rails-like environment:
task :environment do
require File.expand_path(File.join(*%w[ config environment ]), File.dirname(__FILE__))
end
You then have something in config/environment.rb that contains what you need to start up your app properly. It might be something like:
require "rubygems"
require "bundler"
Bundler.setup
require 'sinatra'
Putting this set-up in a separate file avoids cluttering your Rakefile and can be used to launch your Sinatra app through config.ru if you use that:
require File.expand_path(File.join(*%w[ config environment ]), File.dirname(__FILE__))
run Sinatra::Application

Resources