How to Run Ruby Tasks That Use My Rails Models

How do I run Ruby tasks that use my Rails models?

I agree with the answer above but you have to include => :environment in your task or it will not load the Rails environment.

e.g.,

namespace :send do
namespace :trial do
namespace :expiry do
desc "Sends out emails to people who's accounts are about to expire"
task :warnings => :environment do
User.trial_about_to_expire.has_not_been_notified_of_trial_expiry.each do |user|
UserMailer.deliver_trial_expiring_warning(user)
user.notified_of_trial_expiry = true
user.save
end
end
end
end
end

Run a script that uses my models

Try creating a rake task for it. Then just

rake my_tasks:task_name

More info on custom rake tasks can be found here

accessing rails models from rake task

To access a rails model in your rake task you need to load the :environment.

task :my_task => [:environment] do
User.new #...
end

You would not call the scheduler within a task but the other way around. You need to start a Rufus scheduler and then call your rake tasks from them.

You need to first

# other require statements ...
require 'rake'

# ...

scheduler = Rufus::Scheduler.start_new
scheduler.cron "00 6 * * *" do
Rake::Task["sometask"].invoke
end

Need to run tasks on several rails models. Can I use an array do loop?

You're almost there, just use the class objects directly, like so:

my_models = [Category, Hierarchy]

my_models.each do |klass|
a_region = klass.find_or_initialize_by_code(:code)
...
...
a_region.save!
end

Do something in a rake task before Rails models are loaded

Just set something at the top of your Rakefile:

ENV['HELLO_RAKE'] = true

require_relative 'config/application'

Rails.application.load_tasks

Instead of using ENV you could, if you wanted, set a constant, e.g. HELLO_RAKE = true and then check defined?(HELLO_RAKE).

An alternative is to just check if the running program is rake:

handle_asynchronously unless File.basename($0) == "rake"

A downside to both of these approaches is that they will be in effect any time you're using Rake, which will include other Rake tasks not related to migrations.

Ruby scripts with access to Rails Models

I have to agree with David here. Use a migration for this. I'm not sure what you want to do, but running it from inside your environment is much, much more efficient then loading up the app environment manually. And since your initial post suggests you're only doing this once, a migration is the way to go:

rails g migration MigrateData

.. generates:

class MigrateData < ActiveRecord::Migration
def self.up
# Your migration code here
end

def self.down
# Rollback scenario
end
end

Of course, you will always want to perform this locally first, using some test data.

How do I run rake tasks within my rails application

If you wish this rake code to run during the request cycle then you should avoid running rake via system or any of the exec family (including backticks) as this will start a new ruby interpreter and reload the rails environment each time it is called.

Instead you can call the Rake commands directly as follows :-

require 'rake'

class SomeModel <ActiveRecord::Base

def self.run_rake(task_name)
load File.join(RAILS_ROOT, 'lib', 'tasks', 'custom_task.rake')
Rake::Task[task_name].invoke
end
end

Note: in Rails 4+, you'll use Rails.root instead of RAILS_ROOT.

And then just use SomeModel.run_rake("ts:reindex")

The key parts here are to require rake and make sure you load the file containing the task definitions.

Most information obtained from http://railsblogger.blogspot.com/2009/03/in-queue_15.html



Related Topics



Leave a reply



Submit