我正在尝试学习 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 方法,它继续“显示”,并将“updateProgress”作为参数“id”传递。我没有过多地摆弄这个,而是劫持了“新”方法,并在每次想要更新下载状态时让我的 jQuery 调用它。请原谅我,在学习基础知识之前,我可能咬得太多。
其次,一次只能一个人使用这个 webapp,因为我不得不使用类变量而不是实例变量。如果我使用实例变量,那么当一个方法查看另一个方法应该设置的值时,它们将为零。阅读为什么会这样,我想我明白了,但是解决方案是什么?有没有一种简单的方法可以在 Rails 的控制器中的方法之间共享值?我在这里发现了一个类似的问题,其中的答案建议在模型中进行计算,但这也适用于我的目的吗?