2017-12-28 23 views
0

진행률 표시 줄과 함께 Ruby에서 CSV 가져 오기 도구를 만들려고합니다. 문제는 입니다. SiteController ProgressBar의 변수가 초기화되지 않습니다. 어떻게 제대로 할 수 있습니까? 컨트롤러의 변수에 액세스 할 수 있어야합니다. 하지만 include를 사용하여 작동하지 않는 이유는 무엇입니까?파일 사이의 Ruby 공유 변수

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 
+3

주 부모 클래스가 이미 그것을했기 때문에'SpecificImporter'가'ProgressBar를 포함 할 필요가 없습니다. – tadman

+1

또한,'set_max_rows '와 같은 것은 Ruby의 정신에 대항하는 것입니다. 해당 속성에 쓸 수 있도록하려면'attr_accessor'를 사용하면'max ='메소드를 얻을 수 있습니다. 명확하게하기 위해 당신은'max_rows' 속성을 호출하여 대신'self.max_rows = l'을 할 수 있습니다. – tadman

답변

0

이 모듈은 방법과 변수의 덩어리입니다. Importer 클래스와 SiteController 사이에 사용할 수있는 저장 용량을 제공하지 않습니다. 서로 상속되지 않는 여러 클래스에서 동일한 메소드를 정의 할 수있는 기능을 제공합니다. 그것은 Mixin 패턴과 같습니다 (이 설명을보십시오 : https://en.wikipedia.org/wiki/Mixin).

"파일간에 변수를 공유하려면"Redis 또는 Memcached와 비슷한 것을 사용해야합니다. 그래서 여기에 약간의 https://www.sitepoint.com/introduction-to-using-redis-with-rails/

을 :

이 가이드를 살펴 보자 그것을 작동하는 방법을 이해하기 위해) = 정규 SQL의 DB도이 기능을 제공 할 수 있지만,이 경우에는 이렇게 적용되지 않습니다 당신의 예제의 개선은 분명히 (더 나은 솔루션은 레디 스에서 카운터를 구현하거나 레디 스에 부하를 감소 그래서 모든 10 단계에서 값의하거나 업데이트하는 것입니다하지만 합병증입니다.) 만들려면) :

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