我正在尝试使用进度条在Ruby中创建CSV导入程序。问题是 SiteController 没有看到ProgressBar的变量被初始化。我怎么能正确地做到这一点?我需要能够访问控制器中的变量。但为什么它无法使用include? p>
class SpecificImporter < Importer
include ProgressBar
def import
....
custom logic
Thread.new do
@rows.each do |r|
increment_bar
end
end
end
class Importer
attr_accessor :file
include ProgressBar
def calculate_max_rows
l = File.open(@file.path).count
set_max_rows(l)
end
end
module ProgressBar
attr_reader :cur,:max
def increment_bar
@cur += 1
end
def set_max_rows(val)
@max = val
end
def progress
@cur / @max
end
end
class SiteController < ApplicationController
include ProgressBar
def update_progress
..
#send data using json every x seconds
..
status = progress
end
end
答案 0 :(得分:0)
该模块只是一大堆方法和变量。它不会为您提供可在Importer
课程和SiteController
之间使用的存储空间。它只是为您提供了在几个类中定义相等方法的能力,这些方法不是相互继承的。它类似于Mixin模式(请看一下这个描述:https://en.wikipedia.org/wiki/Mixin)。
To&#34;在文件之间共享变量&#34;你应该使用类似于Redis或Memcached的东西。常规SQL DB也可以提供此功能,但在这种情况下它不会如此有效=)
请查看本指南,了解它应如何运作:https://www.sitepoint.com/introduction-to-using-redis-with-rails/
所以这里有一点改进你的例子来说清楚(更好的解决方案是在redis中实现计数器或者在每10步左右更新它的值,以减少redis上的负载。但它是一个并发症)):
module ProgressBar
attr_accessor :curr, :max
def increment_bar
@curr += 1
save_progress # <- Save progress on each step
end
def progress
@curr / @max
end
def save_progress(process_id)
$redis.set("progress_#{process_id}", progress)
end
def load_progress(process_id)
$redis.get("progress_#{process_id}") || 0
end
end
class Importer
include ::ProgressBar
def calculate_max_rows
# some logic will go here...
set_max_rows(l)
end
end
class SpecificImporter < Importer
def import
# custom logic...
increment_bar
end
end
class SiteController < ApplicationController
include ProgressBar
def update_progress
# some logic here...
status = load_progress(params[:process_id]) # <- Load stored progress
end
end