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
Related
I have a problem when I do:
namespace :xaaron do
task :get_roles do
roles = Xaaron::Role.all
puts roles
end
task :get_role, [:name] do |t, args|
role = Xaaron::Role.find(args[:name].parameterize)
puts role
end
end
The first task will work fine. I can even add binding.pry and run Xaaron::Role and get information about Roles back. But the second task fails with:
NameError: uninitialized constant Xaaron::Role
I run each task in my main app because these tasks are inside an engine, using:
bin/rake xaaron:get_roles` and `bin/rake xaaron:get_role
I can run bin/rails c in the main application that uses the engine and run Xaaron::Role and get information about Roles table.
Why is the second one failing but the first one is not? Is there scoping with arguments?
I'm not sure why either works, but if this is Rails and those are Rails models, your tasks should depend on the environment:
task :get_roles => [ :environment ] do
By depending on the :environment task, it first loads Rails.
Also see: What's the 'environment' task in Rake?.
You can also run a Rake task as
bundle exec rake environment xaaron:get_role
This will load the Rails environment first.
I kept getting uninitialized constant errors for a Rake task, even after depending on :environment and running with bundle exec.
The issue was that I was making a Rake::TestTask and, even though the Rake task had access to all constants, the test files themselves did not have access to constants.
The solution was to add this line to the top of my test file:
require_relative '../config/environment'
This is the Rake task:
require "rake/testtask"
Rake::TestTask.new(:test) do |t|
t.libs << "test"
t.libs << "lib"
t.test_files = FileList["test/**/test_*.rb"]
end
To add, as of Ruby 1.9 and above, you can use this hash syntax:
namespace :xaaron do
desc "Rake task to get roles"
task get_roles: :environment do
roles = Xaaron::Role.all
puts roles
end
#####
end
And then you can run the command below to run the Rake task:
rake xaaron:get_roles
or
bundle exec rake xaaron:get_roles
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
I'm trying to test a rake task and it uses an active record in it.
require 'spec_helper'
require 'rake'
load File.join(Rails.root, 'lib', 'tasks', 'survey.rake')
describe "survey rake tasks" do
describe "survey:send_report" do
it "should send a report" do
Rake::Task['survey:send_report'].invoke
end
end
end
When I run this spec rspec spec/lib/survey_spec.rb, I get this error "
RuntimeError:
Don't know how to build task 'environment'
How do I load the :enviroment task inside by example spec?
I think you should first load the tasks:
require 'rake'
MyRailsApp::Application.load_tasks
and then invoke your task:
Rake::Task['survey:send_report'].invoke
I suspect the problem is that your survey:send_report task depends on :environment but you haven't loaded the file that defines the :environment task. That'll be in rails somewhere, and your main Rakefile loads it.
So, I think if you change
load File.join(Rails.root, 'lib', 'tasks', 'survey.rake')
to
load File.join(Rails.root, 'Rakefile')
it'll work.
Sounds like your take task may need the Rails environment to be loaded. You can stub this out by adding this line to your before(:all) hook:
Rake::Task.define_task(:environment)
Is your task adding the :enviroment to do it before? In your .rake file you should have something like this:
namespace :survey do
# ...
task :send_report => :enviroment do
# ... stuff
end
This is because you need to load the full enviroment to do that task. You can check this railcast to get more information http://railscasts.com/episodes/66-custom-rake-tasks
(This is really a newbie question about Rake & Rails & dependencies in general. Trying to wrap my head around how all this fits together)
Basically, I want a Rake task that acts like seed.rb but is called separately. It adds test data for the development environment, while my seed.rb provides basic data for all environments.
The script, family_seed.rb, uses FactoryGirl to generate some records. It looks like this:
require File.expand_path('../../config/environment', __FILE__)
require './spec/factories'
Family.delete_all
Member.delete_all
zinsser = Factory.create(:family, :last_name=>'Zinsser', :first_name=>'Carl', :sim_id => '500')
blackburn = Factory.create(:family, :last_name=>'Blackburn', :first_name=>'Greg', :sim_id => '501')
It runs fine with bundle exec "ruby db/family_seeds.rb", but my question is how to set it up with Rake. Should the whole thing be placed inside a Rake task? How could I, instead, set up a task that would call the script, while ensuring that the Rails development environment is available when it runs? I'm trying not just to get the job done, but to do it in a "right" way.
One way to approach this would be to create a class or module in lib (this makes it easier to write tests for, and makes the code more reusable):
require '../spec/factories'
class FamilySeed
def self.seed
raise "Don't run this in production!" if Rails.env.production?
Family.delete_all
Member.delete_all
zinsser = Factory.create(:family, :last_name=>'Zinsser', :first_name=>'Carl', :sim_id => '500')
blackburn = Factory.create(:family, :last_name=>'Blackburn', :first_name=>'Greg', :sim_id => '501')
end
end
How to create the rake task:
require 'family_seed'
namespace :seed do
task :families => :environment do
FamilySeed.seed
end
end
I'd be careful with allowing things like Family.delete_all and Member.delete_all to be too freely used. You could easily shoot yourself in the foot later on by calling something you didn't mean to on a production db.
How to run the rake task:
Run it in your command like with the following:
bundle exec rake seed:families
Create a rake task and require :environment
task :delete_all => :environement do
require Rails.root.join('spec/factories')
Family.delete_all
Member.delete_all
zinsser = Factory.create(:family, :last_name=>'Zinsser', :first_name=>'Carl', :sim_id => '500')
blackburn = Factory.create(:family, :last_name=>'Blackburn', :first_name=>'Greg', :sim_id => '501')
end
After you can run this task rake delete_all
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