Ruby在文件之间共享变量

时间:2017-12-28 19:24:24

标签: ruby-on-rails ruby

我正在尝试使用进度条在Ruby中创建CSV导入程序。问题是 SiteController 没有看到ProgressBar的变量被初始化。我怎么能正确地做到这一点?我需要能够访问控制器中的变量。但为什么它无法使用include?

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

1 个答案:

答案 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