Heroku, cron.rake and friendly_id gem - ruby-on-rails

I'm using the friendly_id gem.
There's a rake task for deleting old slugs (from the docs):
rake friendly_id:remove_old_slugs MODEL=<model name> DAYS=<days>
It can be run via cron.
Do you know how it should be added to cron.rake (I'm on Heroku)?
Here is my cron.rake:
desc "This task is called by the Heroku cron add-on"
task :cron => :environment do
...
rake friendly_id:remove_old_slugs
end
It produces an error:
"rake aborted! undefined method `friendly_id' for main:Object"
There is no error if I run it from the console (Terminal) like this:
heroku rake friendly_id:remove_old_slugs

Try this:
desc "This task is called by the Heroku cron add-on"
task :cron => :environment do
Rake::Task['friendly_id:remove_old_slugs'].execute
end

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.

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

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

Rails3 plugin - load environment for rake task

What should I do to load rails models for rake task which is part of my plugin?
Require the :environment rake task to run before it.
task :my_task => :environment do
end

Resources