我要先说我是一个相对初学者,虽然我可能还不太了解,但我非常愿意学习。我希望你能帮助解决这个问题,因为我已经尝试了很长时间,但仍然卡住了。我知道这是一个很长的问题——我不会把它扔在这里,除非我已经花了很多天的时间试图先自己弄清楚。
我正在使用 Mechanize 在我的 Rails 应用程序中运行一个脚本来填写几个网络表单。它在本地完美运行。但是,我需要使用delayed_job 才能在后台运行耗时的脚本。目前,我正在本地开发它(以前在 Heroku 上),直到问题得到解决。
所以我安装了delayed_job_active_record gem,并一直试图解决这个问题。我知道,虽然我的表单成功地接收了所有参数,但没有任何东西被插入到 SQL 表中。它没有获取对象的 ID。它不能识别对象的类(它认为它是 NilClass),所以它甚至认为常规的 Ruby 方法(例如 .strip)是未知的。(显示所有这些的控制台输出位于底部)。
我显然做错了什么。这很可能是一件非常明显的事情——但我还没有能力弄清楚这一点。如果你能帮我弄清楚我在这里做错了什么,我将永远感激你。
首先,这是我的代码:
模型:
require 'digest'
class Jumper < ActiveRecord::Base
after_save do |runscript|
runscript.delay.scrape
end
validates :myuserid, :presence => true
validates :mypass, :presence => true
validates :mydate, :presence => true, :numericality => true
validates :mymonth, :presence => true, :numericality => true
validates :myyear, :presence => true, :numericality => true
validates :mylist, :presence => true
attr_accessor :myuserid, :mypass, :mydate, :mymonth, :myyear, :mylist
def scrape
agent = Mechanize.new
page = agent.get('http://mywebsite.org/')
myform = page.form_with(:name => 'signinForm')
myuserid_field = myform.field_with(:name => "email")
myuserid_field.value = myuserid
mypass_field = myform.field_with(:name => "password")
mypass_field.value = mypass
page = agent.submit(myform, myform.buttons.first)
mylistarray = mylist.strip.split(/[\s]+/)
mylistfinal = mylistarray.map{|l| l[0..-5].sub(/(.*)\./,'\1').gsub('.','/')}.uniq
mylistfinal.each do |doi|
url ='http://mywebsite=' + doi + '&role=some_info#some_dates'
page = agent.get("http://mywebsite.org/submit")
page = agent.get("#{url}")
entryform = page.form_with(:name => 'submit')
entryform.field_with(:name => 'month').options[("#{mymonth}").to_i].select
entryform.field_with(:name => 'day').options[("#{mydate}").to_i].select
entryform.field_with(:name => 'year').options[("#{myyear}").to_i].select
page = agent.submit(entryform, entryform.button_with(:name => 'continue'))
end
end
end`
控制器:
def index
@doilists = Doilist.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @doilists }
end
end
def show
@doilist = Doilist.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @doilist }
end
end
def new
@doilist = Doilist.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @doilist }
end
end
def create
@jumper = Jumper.new(params[:jumper])
if @jumper.save
flash[:notice] = "Sucessfully submitted your information."
redirect_to @jumper
else
render :action => 'new'
end
end`
宝石文件:
source 'https://rubygems.org'
gem 'rails'
group :development do
gem 'sqlite3', '1.3.5'
end
group :assets do
gem 'sass-rails', '~> 3.2.5'
gem 'coffee-rails', '~> 3.2.2'
gem 'uglifier', '>= 1.2.3'
end
gem 'jquery-rails', '2.0.2'
gem 'mechanize'
group :production do
gem 'pg', '0.12.2'
end
gem 'delayed_job_active_record'
gem 'daemons'
gem 'thin'`
简介:
web: bundle exec rails server thin -p $PORT -e $RACK_ENV
worker: bundle exec rake jobs:work`
脚本/延迟作业:
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment'))
require 'delayed/command'
Delayed::Command.new(ARGV).daemonize
RAILS_ENV=production script/delayed_job start --exit-on-complete`
这是我在终端中运行 Foreman 时的输出:
11:33:30 web.1 | Started POST "/MyJumper" for 127.0.0.1 at 2013-05-02 11:33:29 -0400
11:33:30 web.1 | Delayed::Backend::ActiveRecord::Job Load (1.2ms) SELECT "delayed_jobs".* FROM "delayed_jobs" WHERE ((run_at <= '2013-05-02 15:33:30.437882' AND (locked_at IS NULL OR locked_at < '2013-05-02 11:33:30.438065') OR locked_by = 'delayed_job host:myroot pid:7081') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 5
1:33:30 web.1 | Processing by JumpersController#create as HTML
11:33:30 web.1 | Parameters: {"utf8"=>"✓", "jumper"=>{"myuserid"=>"email@gmail.com", "mypass"=>"mypassword123”, "mylist"=>"listitem", "mymonth"=>"4", "mydate"=>"30", "myyear"=>"1"}, "commit"=>"Submit Your Entry"}
11:33:30 web.1 | (0.1ms) begin transaction
11:33:30 web.1 | SQL (21.4ms) INSERT INTO "jumpers" ("created_at", "mydate", "mylist", "mymonth", "mypass", "myuserid", "myyear", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?) [["created_at", Thu, 02 May 2013 15:33:30 UTC +00:00], ["mydate", nil], ["mylist", nil], ["mymonth", nil], ["mypass", nil], ["myuserid", nil], ["myyear", nil], ["updated_at", Thu, 02 May 2013 15:33:30 UTC +00:00]]
11:33:30 web.1 | SQL (0.5ms) INSERT INTO "delayed_jobs" ("attempts", "created_at", "failed_at", "handler", "last_error", "locked_at", "locked_by", "priority", "queue", "run_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) [["attempts", 0], ["created_at", Thu, 02 May 2013 15:33:30 UTC +00:00], ["failed_at", nil], ["handler", "--- !ruby/object:Delayed::PerformableMethod\nobject: !ruby/ActiveRecord:Jumper\n attributes:\n id: 68\n mylist: \n created_at: 2013-05-02 15:33:30.920857000 Z\n updated_at: 2013-05-02
15:33:30.920857000 Z\n myuserid: \n mypass: \n mymonth: \n mydate: \n myyear: \nmethod_name: :scrape\nargs:\n- :jumper\n"], ["last_error", nil], ["locked_at", nil], ["locked_by", nil], ["priority", 0], ["queue", nil], ["run_at", Thu, 02 May 2013 15:33:30 UTC +00:00], ["updated_at", Thu, 02 May 2013 15:33:30 UTC +00:00]]
11:33:30 web.1 | (10.7ms) commit transaction
11:33:30 web.1 | Redirected to `http://mylocalhost:5000/MyJumper/68`
11:33:30 web.1 | Completed 302 Found in 74ms (ActiveRecord: 33.1ms)
11:33:31 web.1 | Started GET "/show/68" for 127.0.0.1 at 2013-05-02 11:33:30 -0400
11:33:31 web.1 | Processing by JumpersController#show as HTML
11:33:31 web.1 | Parameters: {"id"=>"68"}
11:33:31 web.1 | Jumper Load (0.3ms) SELECT "jumpers".* FROM "jumpers" WHERE "jumpers"."id" = ? LIMIT 1 [["id", "68"]]
11:33:34 worker.1 | [Worker(host:myroot pid:10470)] Jumper#scrape failed with NoMethodError: undefined method `strip' for nil:NilClass - 0 failed attempts
11:33:34 worker.1 | [Worker(host:myroot pid:10470)] 1 jobs processed at 0.8520 j/s, 1 failed ...