Run a task after "tmp:clear" - ruby-on-rails

I have a task that want to run after I run rails tmp:clear
namespace :myapp do
task :clear do
# do some stuff
end
end
I've learned that I can do it by enhancing that task:
Rake::Task['tmp:clear'].enhance(['myapp:clear'])
The problem is that when my code is loaded, tmp:clear is undefined, so it fails:
$ rails tmp:clear
rails aborted!
Don't know how to build task 'tmp:clear' (See the list of available tasks with `rails --tasks`)
myapp/lib/tasks/clear.rake:7:in `<top (required)>'

Rails tasks are loaded after local tasks. You need to require 'rails/tasks' before to circumvent that.
Complete solution:
require 'rails/tasks'
namespace :myapp do
task :clear do
puts "do some stuff"
end
end
Rake::Task['tmp:clear'].enhance(['myapp:clear'])

Related

Invoking rake task for specific environment

Hello I'm writing a deploy script(rake task) for my mini project. And I have this part when I invoke the db seed :
Rake::Task['db:seed'].invoke
And also compiling assets :
Rake::Task['assets:precompile'].invoke
So I was wondering is there a way to invoke these tasks in production environment like you would do from a console like this :
RAILS_ENV=production rake db:seed
In Rails, you can do as :
[arup#app (master)]$ rails g task my_namespace my_task1
create lib/tasks/my_namespace.rake
[arup#app (master)]$ cat lib/tasks/my_namespace.rake
namespace :my_namespace do
desc "TODO"
task my_task1: :environment do
end
end
[arup#app (master)]$
Now see the Rakefile is ready for you.
Just open the Rakefile you just created, and define your tasks.
namespace :my_namespace do
task my_task1: :environment do
Rake::Task['db:seed'].invoke
Rake::Task['assets:precompile'].invoke
end
end
Hints is 2.10 Custom Rake Tasks.

Using Rake with Rufus

I'm trying to user rake and rufus, both of which I am new to. I want to have Rufus call my rake task but I am getting the following error. Don't know how to build task 'inbox:process_inbox'
lib/tasks/inbox_tasks.rb
namespace :inbox do
task :process_inbox do
logger = Logger.new(Rails.root.to_s + "/log/scheduler.log")
logger.info "Rufus Here!"
end
end
rufus_scheduler.rb
require 'rufus-scheduler'
require 'rake'
scheduler = Rufus::Scheduler.new
scheduler.every '10s', :first_at => Time.now + 3 do
Rake::Task["inbox:process_inbox"]
end
As #jmettraux (the creator of rufus-scheduler!) has already answered, the problem is that the rake task is defined in a .rb file instead of .rake file.
Adding some more details to help in the future.
While creating a new rake task, you could get the rails generator to automatically create the file with appropriate structure.
Example: Running
> rails g task inbox process_inbox
create lib/tasks/inbox.rake
will create a file named lib/tasks/inbox.rake with content:
namespace :inbox do
desc "TODO"
task process_inbox: :environment do
end
end
Having a DESC in the task definition is important; that allows for verifying that the rake task is defined and available, by running either rake -T inbox or rake -T | grep inbox
> rake -T inbox
rake inbox:process_inbox # TODO
Could this one help?
How to build task 'db:populate' (renaming inbox_tasks.rb to inbox_tasks.rake)
(did a simple https://www.google.com/?#q=rails+don%27t+know+how+to+build+task ...)

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

Rails.cache.clear fails with undefined method `clear' for nil:NilClass when running in a rake task

Upon following the instructions to create a rake task to clear the cache, when running that rake task:
namespace :cache do
desc "Clears Rails cache"
task :clear do
Rails.cache.clear
end
end
and running that rake task with:
rake cache:clear
I get an error:
undefined method `clear' for nil:NilClass
When running Rails.cache.clear from the rails console, it successfully clears the cache without an error. Why is cache nil on the Rails object in the rake task, but not in the rails console?
Note: I am using dalli and memcache.
To answer Why is => :environment needed?
:environment is a task defined by rails.
When you need to interact with your application models, perform database queries and so on, your custom task should depend on the environment task, as it will load your rails application code.
Rails.cache will return nil if your application is not loaded.
Hence, the error undefined method 'clear' for nil:NilClass
You need to run environment task before your custom clear task.
namespace :cache do
desc "Clears Rails cache"
task :clear => :environment do ## This will run environment task first and then clear task
Rails.cache.clear
end
end
Figured it out. I was missing => :environment after :clear
The below works:
namespace :cache do
desc "Clears Rails cache"
task :clear => :environment do
Rails.cache.clear
end
end
Why is => :environment needed?

'rake' "in order to" 'rake'

To prepare database for my Ruby on Rails 3 application I need to run the following steps in the Terminal:
rake db:create
rake db:migrate
rake db:seed
Is it possible to do all those steps in one? Maybe it is possible running a 'rake' command that will "fire" another 'rake' command... but how?!
You can define your own rake tasks which call other tasks as prerequisites:
# lib/tasks/my_tasks.rake
namespace :db do
desc "create, migrate and seed"
task :do_all => [:create,:migrate,:seed] do
end
end
Normally the body of the task would contain Ruby code to do something, but in this case we are just invoking the three prerequisite tasks in turn (db:create,db:migrate,db:seed).
The empty do-end blocks are not needed, e.g. (for zetetic's answer)
$ cat lib/tasks/my_tasks.rake
# lib/tasks/my_tasks.rake
namespace :db do
desc "create, migrate and seed"
task :do_all => [:create,:migrate,:seed]
end
rake db:create db:migrate db:seed will do all that.
zeteitic got it right, but in the event you don't want to namespace this task under "db", you'd want something more like this:
desc "Bootstrap database."
task :bootstrap => ["db:create", "db:migrate", "db:seed"] do; end
And on the command line:
rake bootstrap
# => create, migrate and seed db

Resources