2012-07-19 4 views
0

그래서이 문제에 대해 며칠간 연구를 해봤습니다. 일반적인 합의는 하나도 존재하지 않는다는 것입니다. 그래서 내 상황에 더 구체적인 대답을 기대하고 있었어요 ...Ruby에서 클래스 변수 사용 및 편집?

나는 파일을 데이터베이스로 가져 오기 위해 레일을 사용하고 있습니다. 가져 오기와 관련된 모든 작업이 있지만 모든 항목이 아니라 데이터베이스 자체에 특성을 부여하려고합니다. 파일의 해시를 만들고 데이터베이스 (또는 클래스)에 할당하는 것이 가장 쉽다는 것을 알았습니다.

저는 두 개의 속성이있는 각 항목에 Issue (따라서 'issues'데이터베이스)라는 클래스를 만들었습니다. 나는 클래스 변수를 추가하는 방법을 알아 내려고했다. (최소한, 그것은 최선의 선택이라고 생각한다.) 단순히 해시를 저장하기 위해 Issue로 옮긴다. 새 파일이 이전에 가져온 파일과 다른 경우 파일을 가져 오기 위해 레이크를 작성했습니다 (해시가 다른 경우 읽기). 내 모델을 작성하는 여러 가지 방법을 시도했습니다

class Issue < ActiveRecord::Base 

    attr_accessible :md5 

    @@md5 = 5 

    def self.md5 
    @@md5 
    end 

    def self.md5=(newmd5) 
    @@md5 = newmd5 
    end 

    attr_accessible #various database-entry attributes 
end 

하지만, 모든이에 내려 오는 다음과 같이

desc "Parses a CSV file into the 'issues' database" 
task :issues, [:file] => :environment do |t, args| 
    md5 = Digest::MD5.hexdigest(args[:file]) 
    puts "1: Issue.md5 = #{Issue.md5}" 

    if md5 != Issue.md5 
    Issue.destroy_all() 
    #import new csv file 
    CSV.foreach(args[:file]) do |row| 

     issue = { 
     #various attributes to be columns... 
     } 
     Issue.create(issue) 
    end #end foreach loop 
    Issue.md5 = md5 
    puts "2: Issue.md5 = #{Issue.md5}" 
    end #end if statement 
end #end task 

그리고 내 모델입니다. 내 모델에서 @@ md5를 설정하면 무엇이든 상수와 거의 같은 영구적 인 변화가됩니다. 이 값을 여기에서 변경하고 데이터베이스를 새로 고치면 변경 사항이 즉시 표시됩니다. 레일 콘솔에 들어가서 다음을 수행하면 :

Issue.md5  # => 5 
Issue.md5 = 123 # => 123 
Issue.md5  # => 123 

그러나이 변경 사항은 무엇이든 적용되지 않습니다. 콘솔을 종료하자마자 모든 것이 "5"로 다시 돌아갑니다. 내 클래스에 .save 메서드가 필요한 것과 거의 비슷합니다.

또한 레이크 파일에는 구문 분석 전후에 Issue.md5를 출력하는 두 개의 print 문이 있습니다. 첫 번째는 "5"를 출력하고 두 번째는 올바른 새 해시를 출력합니다. 그래서 Ruby는 내가이 변수를 변경한다는 사실을 인식하고 있습니다. 단지 아무 곳에도 저장되지 않습니다.

루비 1.9.3, 레일즈 3.2.6, SQLite3 3.6.20.

tl; dr 클래스 변수를 만들고 액세스하고 수정하고 다시 저장할 수있는 방법이 필요합니다.

수정 하시겠습니까? 감사!

답변

0

여기에는 몇 가지 해결책이 있습니다. 본질적으로, 당신은 그 하나의 변수를 유지할 필요가 있습니다 : Postgres는 가장 이상적인 데이터베이스의 키/값 저장소를 제공합니다. 그러나 SQLite를 사용하고있어 옵션이 아닙니다. 대신이 정보를 데이터베이스에 유지하려면 redis 또는 memcached 중 하나를 사용해야합니다.

둘 중 하나를 사용하면 값이없는 스키마가없는 데이터 스토어에 값을 저장하고 나중에 다시 쿼리 할 수 ​​있습니다. Redis는 디스크에 저장되는 이점이 있으므로 서버가 다시 작동하면 다시 시작할 때 md5 값을 다시 얻을 수 있습니다. memcached에 저장된 데이터는 절대로 지속되지 않으므로 memcached 인스턴스가 사라지면 다시 돌아올 때 md5는 다시 5가됩니다.

redismemcached은 모두 Ruby 커뮤니티에서 많은지지를 얻고 있습니다. 스택을 약간 설치하면 스택이 복잡해 지겠지만 가장 좋은 솔루션이라고 생각합니다. 즉, 둘 중 하나만 사용할 수 없다면 서버의 임시 파일에 md5 값을 쓰고 나중에 다시 액세스 할 수 있습니다. 문제는 그 값이 모든 서버 프로세스간에 공유되지 않는다는 것입니다.

+0

좋아요, 확실히 확인해 보겠습니다. 그들은 내 문제에 대한 확실한 해결책처럼 보입니다. 쉬운 방법이 없습니까? 어쩌면 자바 개발자로서 나는 하하 일을 할 수 있었지만 루비는 클래스 변수와 관련하여 아무 것도 좋아하지 않는 것 같다 ... –

+0

클래스 변수는 클래스 당 정보를 유지하는 데는 문제가 없지만 각 Ruby 프로세스 자체 클래스 변수를 가지며 함께 공유되지 않습니다. 서로간에 보이지 않는 여러 개의 동시 프로세스가 실행되는 Rails와 같은 환경에서는 유용하지 않습니다. 즉, 클래스 변수를 사용하고 공유하려는 경우 [drb] (http://segment7.net/projects/ruby/drb/introduction.html)를 확인하십시오. Ruby 프로세스는 서로간에 정보를 검색하고 공유 할 수 있습니다. – Veraticus

+0

흥미 롭다. 알았어, 고마워. 나는 redis로 시작해서 거기서부터 일할 것이라고 생각합니다. 나는 당신에게 녹색 체크 마크를 조금 줄 것이다, 나는 단지 다른 의견이 거기에 있는지보고 싶다. 감사! –