Rails defining task - ruby-on-rails

i've got several tasks like this:
desc "Generate and send something"
task(:generate_something => :environment) do
Those were situtated in lib/tasks
Is there any possibility to don't set up the environment? I want that the task find out by it selve which environment is active at the moment?

You can simply test the Rails.env variable as in the app itself:
desc "Test task"
task :blaff do
puts Rails.env
puts Rails.env.production?
end
Now you can run this in any environment you want:
% rake blaff
development
false
% RAILS_ENV=production rake blaff
production
true
% RAILS_ENV=test rake blaff
test
false

Related

Run rake task from Capistrano if it exists

I need to a create a Capistrano pre-deploy step that runs a custom rake task.
in deploy.rb:
before 'deploy:starting', 'db:rollback_staging'
namespace :db do
desc 'Rollback staging db only if PR already deployed requires rollback'
task :rollback_staging do
on roles(:master) do
within current_path.to_s do
with rails_env: 'staging' do
execute :rake, 'release:rollback_staging'
end
end
end
end
end
The problem is that when deploying this code the rake task is not yet present on the server and therefore deploy fails with:
rake stdout: rake aborted!
Don't know how to build task 'release:rollback_staging' (See the list of available tasks with `rake --tasks`)
If there a way to check if the rake task exists from Capistrano?
smth like:
with rails_env: 'staging' do
execute :rake, 'release:rollback_staging' if rake_exists? 'release:rollback_staging'
end
I ended up just ignoring not 0 exit code from a rake task using raise_on_non_zero_exit: false:
with rails_env: 'staging' do
execute :rake, 'release:rollback_staging', raise_on_non_zero_exit: false
end
Would this work? Saw this pattern in https://github.com/AgileConsultingLLC/capistrano3-delayed-job
if Rake::Task.task_defined?('release:rollback_staging')

How can I write a Rake task which depends on task with namespace and parameter

I have rake tasks which installs and starts neo4j.
rake neo4j:install[community-latest, stable]
rake neo4j:start[stable] where `stable` is environment.
Now I want to write another rake task something like rake setup and create dependency on rake neo4j:start[stable] and rake neo4j:install[community-latest, stable]
I have tried,
task :setup_dev_env => [:neo4j:install[community-latest, stable], :neo4j:start[stable]] do
puts "Created Rake task"
end
obviously this doesn't work, because in the above task neo4j is namespace. Then I have changed my task to something like,
task :setup_dev_env => [:'neo4j:install[community-latest, stable]', :'neo4j:start[stable]'] do
puts "Hello rake task working"
end
so, at least this solved my issue with neo4j namespace, but still couldn't solve the problem.
When I run rake setup_dev_env It says
rake aborted!
Don't know how to build task 'neo4j:install[community-latest, stable]' (see --tasks)
You can modify that task as:
desc 'Some description'
# setup_dev_env is dependent on neo4j:start
task :setup_dev_env,[:stable] => :environment do |t, arg|
param = arg[:stable].nil? ? 'stable' : arg[:stable]
Rake::Task['neo4j:start'].invoke(param)
puts "Created Rake task"
end
You can write your task as follow:
desc 'Some description'
# setup_dev_env is dependent on neo4j:start
task :setup_dev_env,[:stable] => "neo4j:start" do
puts "Created Rake task"
end
The above lines of code accept a parameter stable and pass it to neo4j:start. To use stable parameter in neo4j:start, you must have to receive as like:
desc 'Some description'
# it will be inside namespace neo4j
task :start, [:stable] do |t, args|
puts "Created Rake task #{args.inspect}"
end

Reset database with rake task

I want to use Heroku's scheduler to reset my database once every day.
It's recommended to use rake tasks for the scheduler. This is what I've tried:
task :reset_database => :environment do
`heroku pg:reset MY_DB:URL`
`heroku run rake db:migrate db:seed`
# some other ruby commands
end
But how would I do this correctly, because putting the heroku commands within backticks, which with bash normally works, doesn't work here:
No such file or directory - heroku
Try this rake task:
namespace :reset_database do
desc "Destroy all table entries."
task :all => :environment do
ActiveRecord::Base.connection.tables.each do |table|
if table != 'schema_migrations'
table.singularize.camelize.constantize.destroy_all
end
# Use this if you want to use the normal seeds:
# Rails.application.load_seed
# Use this if you want to run another rake task:
Rake::Task["foo:bar"].invoke
end
end
end

How to fix "uninitialized constant" in a Rake task

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

Create my own rake test:foo task

I have a bunch of tests that aren't unit or functional tests, they're of the format test/foo/special_test.rb
I want to create a rake task like rake test:units that will run all the tests in the foo folder. How do I do this?
Edit: I'd actually like rake test:foo to be a little different from rake test:units, in that I do not want it to run when I do simply rake test.
I don't remember where this is from, so unfortunately I can't give proper acknowledgement, but this should work. I say "should" because I've stopped using it, but grabbed it from my git history.
# First, 'reopen' the default :test namespace and create your custom task.
namespace :test do
Rake::TestTask.new(:foo_tests => ["test:prepare", "other_dependent_rake_tasks"] ) do |t|
DatabaseCleaner.strategy = :transaction # If using this.
t.libs << "test"
# Will also get subfolders within test/foo
t.test_files = FileList['test/foo/**/*_test.rb', 'test/foo/*_test.rb']
end
end
You can remove the default "test" task and redefine it so that when you run rake test it will automatically also run rake test:foo_tests.
remove_task "test"
desc 'Adding onto Rails regular tests'
task :test do
# Add all the names of tests you want run here.
errors = %w(test:units test:functionals test:integration test:foo_tests).collect do |task|
begin
puts "Running: #{task}"
Rake::Task[task].invoke
nil
rescue => e
task
end
end.compact
abort "Errors running #{errors * ', '}!" if errors.any?
end

Resources