2008-11-16 11 views
12

Tengo una aplicación Rails con algunos modelos básicos. El sitio web muestra datos recuperados de otras fuentes. Entonces necesito escribir un script de Ruby que cree nuevas instancias en mi base de datos. Sé que puedo hacer eso con los ganchos de prueba, pero no estoy seguro de que tenga sentido aquí.¿Cómo ejecuto las tareas de Ruby que usan mis modelos de Rails?

No estoy seguro de cómo debería ser esta tarea, cómo puedo invocarla o a dónde debería ir en mi árbol de fuentes (lib \ tasks?).

Por ejemplo, aquí es mi primer intento:

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

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

Esto falla porque no puede obtener una conexión a la base de datos. Esto tiene sentido de una manera vaga para mi cerebro novato, ya que presumiblemente Rails está haciendo todo el trabajo de magia detrás de escena para preparar todo eso. Entonces, ¿cómo configuro mi pequeño script?

Respuesta

7

Acepto la respuesta anterior, pero debe incluir =>: entorno en su tarea o no cargará el entorno Rails.

por ejemplo,

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 
1

Puede abrir una conexión en las secuencias de comandos como tal:

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

Estoy seguro de que es una forma más elegante de hacerlo, por lo que agarra la información de su database.yml.

3

Sugiero crear tareas personalizadas de rake (lib/task/foo.rake). Esto le da acceso fácil a la mayor parte de la funcionalidad de su aplicación de rieles.

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

continuación:

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

Incluso puede ejecutar las tareas a través de una tarea programada.

18

que es posible cargar todo el entorno de los carriles en cualquier alfabeto rubí por environment.rb requiriendo simplemente:

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

Esto supone el entorno RAILS_ROOT se establece la variable, véase mi comentario para otras formas de hacer esto.

Esto tiene la ventaja añadida de ofrecerte todas las clases y objetos agradables que tienes en el resto del código de tus rieles.

Para iniciar sus procesos, parece que cron hará lo que quiera, y también agregaría una tarea a su receta capistrano que agregaría su script al crontab para obtener periódicamente los datos de la fuente externa y actualizar su DB. Esto se puede hacer fácilmente con la gema cronedit.

El enfoque de cron tiene algunos inconvenientes, sobre todo sobrecarga y control, para otras opciones más sofisticadas ver HowToRunBackgroundJobsInRails de la wiki de rails.

+1

¿Se da cuenta de que RAILS_ROOT no está definido hasta que environment.rb ya se haya cargado? :-) –

+0

Orion es muy correcto. Así que edité lo anterior para buscar la variable de entorno. También podría proporcionar una ruta completa o usar una relativa a su secuencia de comandos con "# {File.dirname (__ FILE __)}/path/to/env" – csexton

1

Hay pocos pasos para esto y más detalles necesarios para responder muy bien.

¿Dice que su sitio recupera datos de otras fuentes? ¿Con qué frecuencia? Si es semi-regular, definitivamente debe considerar el procesamiento de fondo/mensajes.Si es con frecuencia lo que realmente desea es evitar cargar su entorno de raíles cada vez que se ejecuta su secuencia de comandos, ya que pagará un impuesto de inicio demasiado alto cada vez.

Hay una multitud de opciones que desearás investigar. Leer sobre cada uno de ellos, en particular las opiniones de las personas que publican sobre por qué hicieron la elección que eligieron, le dará una buena idea de las preguntas que debe hacerse antes de elegir. ¿Qué tan grande es un trabajo cargando los datos? etc ...

De la parte superior de mi cabeza Estas son algunas de las cosas que puede que desee ver en

script/corredor & Cron Antecedentes/RB Starling Workling MemcacheQ Beanstalk Antecedentes de empleo (Bj) delayed_job (Dj) Daemon Generator

1

Compruebe hacia fuera mi respuesta en "A cron job for rails: best practices?".

Contiene dos ejemplos para usar cron para ejecutar tareas de Rake y métodos de clase (a través de script/runner). En ambos casos, Rails está cargado y puede usar sus modelos.

+0

Gracias ... Esta no era la publicación que estaba buscando, pero su solución abrió nuevas posibilidades para mí ...: D –

0

¡La manera más fácil de ejecutar tareas de ruby ​​que interactúan con aplicaciones/modelos de rieles es hacer que Rails genere tareas de Rake para usted! :)

He aquí un ejemplo

  1. plazo rails g task my_namespace my_task

  2. Esto generará un archivo llamado lib/tasks/my_namespace.rake que se parece a:

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. Ejecute esta tarea con rake my_namespace:my_task

  2. ¡Mire su tarea de código ruby ​​que interactúa con la ejecución modal de rieles!

Cuestiones relacionadas