Tuesday, 17 September 2013

How do I share variables between methods in a controller in Rails 4?

How do I share variables between methods in a controller in Rails 4?

I'm trying to learn Ruby on Rails, so one of the projects I am doing is
developing an app where you enter a URL, click submit, the server starts
downloading the file from that URL, and then you see a page showing you
the details of the download (periodically updated from the server). I
haven't gotten my head around some of the idiosyncrasies of instance
variables vs. class variables in Ruby, and I have done something horrible:
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
First of all, I wasn't able to get it to call the updateProgress method,
it kept going to "show", and passing "updateProgress" as the parameter
"id". Instead of fiddling too much with this, I just hijacked the "new"
method and had my jQuery call that every time it wants an update on the
download status. Forgive me for this, I probably bit off more than I can
chew before learning the basics.
Secondly, only one person can use this webapp at a time, because I had to
use class variables instead of instance variables. If I used instance
variables then they would be nil by the time one method looked at a value
another method was supposed to have set. Reading up on why that is, I
think I get the idea, but what is the solution? Is there an easy way to
share values between methods in a controller in rails? I've found a
similar question on here where the answers recommended doing the
calculations in the model, but would that work for my purposes as well?

No comments:

Post a Comment