简体   繁体   English

如何运行使用Rails模型的Ruby任务?

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

I have a Rails app with some basic models. 我有一些基本模型的Rails应用程序。 The website displays data retrieved from other sources. 该网站显示从其他来源检索到的数据。 So I need to write a Ruby script that creates new instances in my database. 因此,我需要编写一个Ruby脚本来在数据库中创建新实例。 I know I can do that with the test hooks, but I'm not sure that makes sense here. 我知道我可以使用测试钩来做到这一点,但是我不确定在这里是否有意义。

I'm not sure what this task should look like, how I can invoke it, or where it should go in my source tree (lib\\tasks?). 我不确定该任务应该是什么样,如何调用它,或者它在源代码树中的位置(lib \\ tasks?)。

For example, here's my first try: 例如,这是我的第一次尝试:

require 'active_record'
require '../app/models/mymodel.rb'

test = MyModel.new
test.name = 'test'
test.save

This fails because it can't get a connection to the database. 这失败,因为它无法连接到数据库。 This makes sense in a vague way to my newbie brain, since presumably Rails is doing all the magic work behind the scenes to set all that stuff up. 这对我的新手大脑来说是一种模糊的理解,因为据推测,Rails正在幕后进行所有不可思议的工作来设置所有东西。 So how do I set up my little script? 那么如何设置我的小脚本?

You can load the entire rails environment in any ruby script by simply requiring environment.rb: 您可以只需要environment.rb即可在任何ruby脚本中加载整个Rails环境:

require "#{ENV['RAILS_ROOT']}/config/environment" 

This assumes the RAILS_ROOT environment variable is set, see my comment for other ways of doing this. 假设设置了RAILS_ROOT环境变量,请参见我的评论以了解其他方法。

This has the added bonus of giving you all the nice classes and objects that you have in the rest of your rails code. 这具有额外的好处,即为您提供其余Rails代码中所有漂亮的类和对象。

To kick off your processes it sounds like cron will do what you want, and I would also add a task to your capistrano recipe that would add your script to the crontab to periodically get the data from the external source and update your DB. 要启动您的进程,听起来cron会做您想要的事情,我还要在capistrano配方中添加一个任务,该任务会将您的脚本添加到crontab中,以定期从外部源获取数据并更新数据库。 This can easily be done with the cronedit gem. 使用cronedit gem可以很容易地做到这一点

The cron approach does have some drawbacks, mostly overhead and control, for other more sophisticated options see HowToRunBackgroundJobsInRails from the rails wiki. cron方法确实存在一些缺点,主要是开销和控制方面的问题,有关其他更复杂的选项,请参见rails Wiki的HowToRunBackgroundJobsInRails

I agree with the answer above but you have to include => :environment in your task or it will not load the Rails environment. 我同意上面的回答,但是您必须在任务中包含=>:environment,否则它将不会加载Rails环境。

eg, 例如,

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

I'd suggest creating custom rake tasks (lib/task/foo.rake). 我建议创建自定义的rake任务(lib / task / foo.rake)。 This give you easy access to most of the functionality of your rails app. 这使您可以轻松访问rails应用程序的大多数功能。

namespace :foo do
  desc 'do something cool'
  def something_cool
     test = MyModel.new
     test.name = 'test'
     test.save
  end
end

Then: 然后:

$ rake -T foo
rake foo:something_cool       # do something cool

You can even run the tasks via a cronjob. 您甚至可以通过cronjob运行任务。

You can open a connection in your scripts as such: 您可以这样在脚本中打开连接:

ActiveRecord::Base.establish_connection(
    :adapter  => "mysql",
    :username => "root",
    :host     => "localhost",
    :password => "******",
    :database => "******" 
)

I'm sure there is a more elegant way to do it, so that it grabs the info from your database.yml. 我敢肯定有一种更优雅的方法可以做到这一点,以便它从您的database.yml中获取信息。

There are few steps to this and more details needed to really answer well. 只需执行几个步骤,便需要更多细节才能真正回答。

You say your site retrieves data from other sources? 您说您的网站从其他来源检索数据吗? How often? 多常? If it is semi-regularly you definitely want to look into background processing/messaging. 如果它是半定期的,则您肯定要研究后台处理/消息传递。 If it is frequently you really want to avoid loading your rails environment every time your script runs since you will be paying too high a startup tax each time. 如果经常发生,您确实希望避免在每次脚本运行时都加载Rails环境,因为每次都将支付过高的启动税。

There are a multitude of options out there you will want to research. 您将要研究多种选择。 Reading about each of them, particularly reviews from people who post about why they made the choice they did, will give you a good feel for what questions you need to ask yourself before you make your choice. 阅读其中的每一个,特别是发表了他们为什么做出选择的人的评论,将使您对做出选择之前需要问自己的问题有一个很好的感觉。 How big a job is loading the data? 正在加载多少工作? etc... 等等...

Off the top of my head these are some of the things you may want to look into 在我的头顶上,这些是您可能需要研究的一些东西

Script/Runner & Cron Background/RB Starling Workling MemcacheQ Beanstalk Background Job (Bj) delayed_job (Dj) Daemon Generator 脚本/运行者和Cron后台/ RB Starling工作MemcacheQ Beanstalk后台作业(Bj)delay_job(Dj)守护程序生成器

Check out my answer in " A cron job for rails: best practices? ". 在“ 铁轨工作:最佳实践? ”中查看我的答案。

It contains two examples for using cron to run Rake tasks and class methods (via script/runner ). 它包含两个使用cron运行Rake任务和类方法的示例(通过script/runner )。 In both cases, Rails is loaded and you can use your models. 在这两种情况下,都会加载Rails,并且可以使用模型。

尼斯Joyent的编写使用耙运行升轨道从cron作业任务- http://wiki.joyent.com/accelerators:kb:rails:cron

Easiest way to run ruby tasks that interact with rails app/models is to make Rails generate Rake tasks for you!! 运行与Rails应用程序/模型交互的ruby任务的最简单方法是使Rails为您生成Rake任务! :) :)

Here's an example 这是一个例子

  1. run rails g task my_namespace my_task 运行rails g task my_namespace my_task

  2. This will generate a file called lib/tasks/my_namespace.rake which looks like: 这将生成一个名为lib/tasks/my_namespace.rake的文件,如下所示:

namespace :my_namespace do
desc "TODO: Describe your task here"
  task :my_task1 => :environment do
    #write any ruby code here and also work with your models
    puts User.find(1).name
  end
end
  1. Run this task with rake my_namespace:my_task 使用rake my_namespace:my_task运行此任务

  2. Watch your ruby code task that interacts with rails modal run! 观看与rails模态运行交互的ruby代码任务!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM