2

私は比較的初心者であり、まだあまり理解していないかもしれませんが、喜んで学びたいと思っています。私は長い間これを理解しようとしてきましたが、まだ立ち往生しているので、あなたがこれを手伝ってくれることを願っています. 私はこれが長いものであることを知っています-最初に自分でそれを理解しようとして何日も費やしていない限り、私はここでそれを捨てません.

Mechanize を使用して、Rails アプリでスクリプトを実行し、いくつかの Web フォームに入力しています。ローカルで完璧に機能しました。ただし、時間のかかるスクリプトをバックグラウンドで実行するには、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`

スクリプト/delayed_job:

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 ...
4

2 に答える 2

0

ご提案いただきありがとうございます。私はこれを自分で解決する方法を考え出すことになりました。どうやら問題はattr_accessor、Rails 3 で Delayed_Job に重大な問題があることでした。

詳細については、こちらを参照してください: delayed_job: レール 2 からアップグレードした後、属性アクセサー値がレール 3 のdelayed_jobs テーブルに格納されない

そしてここ: YAML、delayed_job : Psych vs Syck. pysch に ruby​​ オブジェクトの attr_accessors を読み込ませる方法

この問題の回避策は、 https ://gist.github.com/jrafanie/3011499 で説明されています。

attr_accessorモデルの一部を削除するだけで、すべてが完全に機能します。なんという安堵!

また、コントローラーがオブジェクトを保存した直後に、after_saveモデルからコードを削除し、コントローラーに単純に追加しました。@jumper.delay.scrapeこれは必要ないかもしれませんが、ドキュメンテーションとより一貫しています:

if @jumper.save
    @jumper.delay.scrape 
    flash[:notice] = "Currently sending your info"
    redirect_to start_index_path 

本番環境に移行する際に、回避策をさらに検討し、モデルに attr_accessor を含めることができるようにプロジェクトに最適な方法を見つけます。しかし、今のところ、これが機能していることをうれしく思います。

于 2013-05-06T19:08:56.340 に答える