我正在尝试学习Ruby on Rails,所以我正在开发一个应用程序。在这个应用程序中,您可以输入URL,点击提交按钮,服务器开始从该URL下载文件,然后您可以看到一个页面,显示下载的细节(从服务器定期更新)。我还没有完全理解Ruby中实例变量和类变量的差异,我犯了一个错误:
class ProgressWebsController < ApplicationController
layout "application"
include ActionController::Live
before_action :set_progress_web, only: [:edit, :update, :destroy]
@@thread
@@test=0
@@clonePW
# GET /progress_webs
# GET /progress_webs.json
def index
@progress_web=ProgressWeb.new
end
def updateProgress
puts "Not gonna happen"
end
# GET /progress_webs/1
# GET /progress_webs/1.json
def show
puts "Downloading %s" % @@clonePW['url'].to_s
@@thread = download(@@clonePW['url'].to_s)
@progress_web=@@clonePW
@@start = Time.now
end
# GET /progress_webs/new
def new
if( @@test.eql?("100.00"))
puts "DOWNLOAD COMPLETE"
@@thread.exit
render :partial => "complete", :locals => { :progress_int => @@test, :done_int =>@@done, :elapsed_int =>@@elapsed_int }
return
end
@@test= "%.2f" % @@thread[:progress].to_f
@@done= "%d" % @@thread[:done]
now = Time.now
elapsed =now - @@start
@@elapsed_int="%d" % elapsed
render :partial => "progress", :locals => { :progress_int => @@test, :done_int =>@@done, :elapsed_int =>@@elapsed_int }
end
def download(url)
Thread.new do
thread = Thread.current
body = thread[:body] = []
url = URI.parse url
Net::HTTP.new(url.host, url.port).request_get(url.path) do |response|
length = thread[:length] = response['Content-Length'].to_i
response.read_body do |fragment|
body << fragment
thread[:done] = (thread[:done] || 0) + fragment.length
thread[:progress] = thread[:done].quo(length) * 100
end
end
end
end
首先,我无法调用updateProgress方法,它一直跳到“show”,并将“updateProgress”作为参数“id”传递。为了避免过多的折腾,每次需要更新下载状态时我都会劫持“new”方法,并让jQuery调用该方法。对不起,我可能在学习基础知识之前就想得太多了。
其次,一次只能有一个人使用这个Web应用程序,因为我必须使用类变量而不是实例变量。如果我使用实例变量,那么另一个方法应该设置的值会被设为空值。阅读了解释之后,我认为我理解了其中的道理,但解决方案是什么呢?在Rails控制器中有没有一种简单的方法可以在方法之间共享值?我在这里找到了一个类似的问题,答案建议在模型中进行计算,但对于我的情况是否也适用呢?