我正在编写一个应用程序,它将在指定的文件夹中运行脚本,然后记录数字并绘制图形。
我的问题是,如果脚本是一个ruby文件,那么require语句会在脚本中失败,因为bundler似乎已经在加载路径上做了一些时髦的事情。
正在运行rails runner Datasource.run_jobs
失败:
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 :(得分:2)
(根据你对这个问题的评论)
您需要将hpricot(以及此需要的任何其他gem)添加到Gemfile
,以便Bundler可以使用它们。截至目前,Bundler 是避免宝石冲突和蠢事的最简单方法。
想象一下这种情况:你以某种方式失去了你目前拥有的宝石。通过格式或系统更改或任何其他原因发生这种情况。不管是什么,你都失去了宝石。你打算如何重新安装所有的宝石?你可以自己在其他地方保留一份清单,但这真的可能吗?
Bundler通过让您说明应用程序所需的gems并仅将这些gem添加到加载路径来解决此问题,这就是您找不到hpricot
的原因。当您第一次运行bundle install
时,会创建一个Gemfile.lock
,其中包含以下内容:
GEM
remote: http://rubygems.org/
specs:
abstract (1.0.0)
actionmailer (3.0.0)
...
因为您将此文件提交到您选择的源代码控制“解决方案”(无论是Git,SVN,FTP,无论如何,这都不重要),您可以通过一种可靠的方式来指定这些宝石的精确宝石和精确版本。应用程序使用。
当/如果您的宝石被擦除,您可以再次克隆您的项目并运行bundle install
。由于Gemfile.lock
文件存在,即使有更新,您也会拥有与之前完全相同的宝石。
如果您不希望完全相同的宝石,只需运行bundle update
,这将忽略Gemfile.lock
中的规范,而是依赖于{{1}定义它们。这将检查新版本的gem并安装它们,并在完成后更新Gemfile
。
老实说,我不理解Bundler的仇恨。如果你能用比“OMG IT SUCKS YEHUDA IS SATAN”更广泛的术语来解释,我会非常感激。
编辑:WedTM要求提供示例Gemfile及相关代码:
在Gemfile中你有这个:
Gemfile.lock
为脚本要求这些宝石:
group(:scripts) do
gem 'gem1'
end
您可能还需要默认的宝石,只需在require 'bundler'
Bundler.require(:scripts)
的参数中添加默认值即可:
require
如果由于某种原因这不起作用,我会想象它会找不到Bundler.require(:default, :scripts)
。可以通过将Gemfile
设置为ENV['BUNDLE_GEMFILE']
的路径来解决此问题。
答案 1 :(得分:1)
我想知道您是否可以在运行脚本之前使用RVM来设置ruby环境。也许像宝石这样的东西:
data = `rvm gemset use scripts; #{RAILS_ROOT}/lib/plugins/#{ds.name}`