2010-09-04 4 views
1

J'écris une application qui va exécuter des scripts dans un dossier spécifié, puis enregistrer les chiffres et les représenter graphiquement.Rails 3, Bundler, LoadError

Mon problème est que si le script est un fichier ruby, les instructions require échouent dans le script car bundler semble avoir fait quelque chose de funky avec le chemin de chargement.

Exécution rails runner Datasource.run_jobs échoue:

class Datasource < ActiveRecord::Base 
    def self.run_jobs 
    require 'aws_sdb' 
    access_key_id = "REDACTED" 
    secret_key = "REDACTED" # In all actuality these woudln't be here. 
    @sdb = AwsSdb::Service.new(:access_key_id => access_key_id, :secret_access_key => secret_key) 

    Datasource.all.each do |ds| 
     puts "Updating #{ds.name}..." 
     unless @sdb.list_domains.include? ds.name 
     puts "#{ds.name} doesn't exist in SDB, creating a domain for it..." 
     @sdb.create_domain ds.name 
     end 

     #data = "TEST" 
     data = `#{RAILS_ROOT}/lib/plugins/#{ds.name}` 

     @sdb.put_attributes(ds.name, Time.now.to_i, data) 
     puts "Data Collected: #{data.inspect}" 
    end 
    end 

    has_many :graphs 

end 
+0

S'il vous plaît montrez-nous votre Gemfile. –

+0

Échec avec quel message d'erreur? –

+0

@Ryan Bigg, je ne veux pas avoir besoin de chaque gemme dans mon Gemfile. Je veux avoir un dossier plein de scripts, (ruby et non-ruby) que ruby ​​va parcourir avec des backticks et s'exécuter sur le système. La sortie de chacun de ces fichiers sera ensuite enregistrée par l'application my rails dans la base de données. Avoir ceux qui dépendent des gemmes dans l'application Rails ne devrait PAS être une exigence. Je devrais être capable de l'exécuter dans le contexte natif des systèmes. – WedTM

Répondre

2

(Fonder ce vos commentaires sur la question)

Vous devrez ajouter hpricot (et tout autre bijou ce besoin) à votre Gemfile afin qu'ils soient mis à disposition par Bundler. Bundler est de loin le moyen le plus facile d'éviter les conflits de gemme et de la cocotte. Imaginez cette situation: Vous perdez en quelque sorte les gemmes que vous avez actuellement. Qu'il se passe par un changement de format ou de système ou toute autre raison. Quoi que ce soit, vous avez perdu vos gemmes. Comment allez-vous ré-installer toutes vos gemmes? Vous pourrait garder une liste d'eux ailleurs, mais est-ce vraiment probable? Bundler résout ce problème en indiquant les gemmes requises par votre application et en ajoutant uniquement ces gemmes au chemin de chargement, ce qui explique pourquoi vous ne pouvez pas trouver hpricot. Lorsque vous exécutez bundle install la première fois, cela crée un Gemfile.lock qui contient quelque chose comme ceci:

GEM 
    remote: http://rubygems.org/ 
    specs: 
    abstract (1.0.0) 
    actionmailer (3.0.0) 
    ... 

Parce que vous commettez ce fichier à votre « solution » de contrôle de code source de choix (que ce soit Git, SVN, FTP, quelle que soit, ce n'est pas important), vous avez un moyen précis de spécifier les gemmes précises et les versions précises des gemmes que votre application utilise. Quand/Si vos gemmes sont effacées, vous pouvez simplement cloner à nouveau votre projet et exécuter bundle install. Parce que le fichier Gemfile.lock existe, vous aurez exactement les mêmes gemmes que vous aviez à l'origine, même s'il y avait des mises à jour.

Si vous ne voulez pas les exactes mêmes pierres précieuses, il suffit d'exécuter bundle update et cela va ignorer les spécifications Gemfile.lock et au lieu de revenir à Gemfile en fonction de les définir. Cela va vérifier les nouvelles versions de gems et les installer, mettre à jour le Gemfile.lock quand c'est fait. Honnêtement, je ne comprends pas la haine de Bundler. Si vous pouviez expliquer en termes plus larges que "OMG IT SUCKS YEHUDA EST SATAN", je serais très obligé.

Edit: WedTM demandé un échantillon Gemfile et le code connexe:

Dans le Gemfile vous auriez ceci:

group(:scripts) do 
    gem 'gem1' 
end 

Exiger ces pierres précieuses pour vos scripts:

require 'bundler' 
Bundler.require(:scripts) 

Vous pouvez également demander les gemmes par défaut que vous pouvez faire en ajoutant simplement par défaut n'importe où aux arguments de require:

Bundler.require(:default, :scripts) 

Si cela pour une raison quelconque ne fonctionne pas, j'imagine que ce serait parce qu'il ne peut pas localiser le Gemfile. Cela peut être corrigé en définissant le ENV['BUNDLE_GEMFILE'] sur le chemin d'accès au Gemfile.

+0

Ryan, j'aime vraiment cette partie de bundler, ça le rend plus facile! Cependant, je pense que la partie que vous ne voyez pas dans mon problème, c'est que le fichier qui est en cours d'exécution ne fait PAS partie de mon application rails. C'est juste un script sur le système qui réside dans un dossier. Il se trouve que mon appli rails fait une boucle sur TOUS les fichiers de ce dossier et enregistre sa sortie. Si j'exécute le fichier OUTSIDE de mon application rails, cela fonctionne comme prévu, mais en cours d'exécution dans le contexte de l'application (rampe de rails 'Method.containing_a_call_to_said_script') – WedTM

+0

@WedTM: Ensuite, exigez Bundler, pointez-le sur votre Gemfile et Ensuite, mettez les scripts dans un groupe appelé "script" et incluez-les en utilisant Bundler.require (: script)? –

+0

Ryan, la question et un énorme merci pour vous si vous pouviez me donner un exemple – WedTM

1

Je me demande si vous pourriez utiliser RVM pour configurer l'environnement ruby ​​avant d'exécuter vos scripts. Peut-être quelque chose avec un gemset comme:

data = `rvm gemset use scripts; #{RAILS_ROOT}/lib/plugins/#{ds.name}` 
Questions connexes